「UOJ224」「NOI2016」旷野大计算

题目描述

随着人类计算机技术的发展,计算机的能力不断提升,让跳蚤国王非常羡慕。

终于有一天,跳蚤国王发布政令:大力发展跳蚤国的计算机产业!然而,跳蚤国尚未进行工业革命,无法制造出电子计算机所需的元器件。但是跳蚤国王想出了一个绝妙的想法:把每只跳蚤作为一个计算节点,每只跳蚤只完成一个特定的小任务。

跳蚤国王带领 n 只跳蚤来到了一片旷野上,把跳蚤作为计算节点在旷野上排列好,并编号为 1n。每个计算节点会把某几个(也有可能是 0 个)计算节点的结果作为输入,计算得到输出。除此之外,跳蚤国王还有一个巨型的终端,可以从终端输入和输出数据,这台终端和所有计算节点组成了一台计算机。

记第 t 个计算节点的输出为 xt,该节点的操作可分为以下几种类型:

名称操作符(类型)操作数计算结果
输入节点I从终端读入一个实数作为 xt
输出节点Oixt=xi,并将 xt 输出到终端
加法节点+i,jxt=xi+xj
偏移节点Ci,cxt=xi+c
取反节点-ixt=xi
左移节点<i,kxt=xi2k
右移节点>i,kxt=xi/2k
S型节点Sixt=s(xi)
比较节点Pi,jxt={1xi<xj0xi=xj1xi>xj
Max节点Mi,jxt={xixi>xjxjxixj
乘法节点*i,jx_t = x_i \cdot x_j

其中,s(x) 的定义如下:(e 为自然常数,其值约为 2.718281828459045\dots\begin{equation} s(x) = \frac{1}{1 + e^{-x}} \end{equation} s(x) 的函数图像如下图所示:

sigmoid

上述表格中的操作数 i, j 均要小于当前节点的编号 t,这样随着跳蚤国王的一声令下,跳蚤就可以按编号从小到大的顺序,依次获得输入然后计算输出。每个跳蚤的计算能力都是有限的,他们仅可以精确到十进制小数点后 90 位,超过的部分将会被四舍五入。同理,上述表格中的操作数 c 的小数部分也不能超过 90 位。另外,左移节点和右移节点中的操作数 k 必须是非负整数,且不能超过 10000

把跳蚤排列好后,野心勃勃的跳蚤国王决心测试一下这台由跳蚤组成的计算机的计算能力,于是蝈蝈大臣给跳蚤国王献上了 10 个计算任务。完成每个计算任务均需要从终端获取输入,进行中间计算,再用输出节点将结果输出。具体任务说明如下:

编号输入输入限制输出
1a,b
\lvert a \rvert, \lvert b \rvert \le 10^9
小数部分不超过 9
-2a-2b
2a
\lvert a \rvert \le 10^9
小数部分不超过 9
\frac{1}{1+e^{17a}}
3a
\lvert a \rvert \le 10^9
小数部分不超过 9
\begin{equation}\begin{cases}-1 & a \lt 0 \\ 0 & a = 0 \\ 1 & a \gt 0\end{cases}\end{equation}
4a
\lvert a \rvert \le 10^9
小数部分不超过 9
\lvert a \rvert,即 a<script type="math/tex">a</script> 的绝对值
5a_1, \dots, a_{32}a_1, \dots, a_{32} \in \{0, 1\}a_1, \dots, a_{32} 从左到右看成一个二进制整数,高位在左低位在右,输出该整数的值
6a
0 \le a \lt 2^{32}
a 为整数
输出 32 个整数,从高位到低位输出 a 的二进制表示(不足 32 位的在高位补 0
7a,b
0 \le a, b \lt 2^{32}
a,b 均为整数
a, b 按位异或的结果
8a
\lvert a \rvert \le 10^9
小数部分不超过 9
\frac{a}{10}
9a_1, \dots, a_{16}
\lvert a_1 \rvert, \dots, \lvert a_{16} \rvert \le 10^9
小数部分不超过 9
输出 16 个实数,表示 a_1, \dots, a_{16} 从小到大排序后的结果
10a,b,m
0 \le a, b \lt 2^{32}
1 \le m \lt 2^{32}
a,b,m 均为整数
a \cdot b 除以 m<script type="math/tex">m</script> 的余数

跳蚤国王发现自己没有足够的能力设计这样的计算机。于是他找到了来参加 NOI 的你。请你依次设计每个计算节点的类型及操作数,完成蝈蝈大臣给的这 10 个计算任务,且要求使用的计算节点数尽量少。

输入格式

所有输入数据 nodes1.in~nodes10.in 见数据下载,分别对应 10 个计算任务。

每组输入数据仅包含一个整数,表示需要解决的计算任务编号。

输出格式

输出文件为 nodes1.out~nodes10.out,分别对应相应的输入文件。

对于每组输入数据,你需要依次输出若干行,第 i 行描述第 i 个计算节点。

描述每个计算节点时,首先一个字符表示该计算节点的类型,接下来若干个数按顺序表示该计算节点的内置参数。字符与数,数与数之间均用空格隔开。

输出的行数不能超过 10^4 行。

样例一

input
1

output
I
+ 1 1
- 2
I
+ 4 4
- 5
+ 3 6
- 7
- 8
O 9

explanation

该样例输出为第一个计算任务一个可能的构造。共用了 10 个计算节点,可获得 3 分。

子任务及部分分

我们提供了十个评分文件 nodes1.ans~nodes10.ans,分别对应每个计算任务。

每个评分文件共 10 行,第 i 行一个评分参数 w_i,具体意义将在下面给出。

本题中,每个测试点单独进行评分,每个测试点 10 分。

如果选手的输出格式不合法或者参数不符合题目约定,则得 0 分。

否则,按照以下规则判定选手的输出是否正确:

首先测评器会生成若干组输入数据,并将输入数据代入你构造的计算机。

如果在代入某一组输入数据时:你构造的计算机的计算过程中,某个计算节点的计算结果的绝对值超过 10^{1000},则得 0 分;你构造的计算机的输出中的某个值与预期的输出值相差超过 10^{-9},则认为你的输出不正确,得 0 分。

否则,我们认为你的计算机能完成给定的计算任务,并按照以下规则得分。

对于每个测试点,我们设置了 10 个评分参数 w_1 , w_2 , w_3 , \dots , w_9 , w_{10}

假设共使用了 n<script type="math/tex">n</script> 个计算节点,你的分数将会由下表给出:

得分条件得分条件
10n \le w_{10}5n \le w_5
9n \le w_{9}4n \le w_4
8n \le w_{8}3n \le w_3
7n \le w_{7}2n \le w_2
6n \le w_{6}1n \le w_1

若不符合表中所有条件,得 0 分;若符合表中的多个条件,则取分数最高的。

除此之外,使用比较节点、Max 节点和乘法节点的代价是极为昂贵的。因此,这三种节点每使用一种,就会从你这个测试点的得分中倒扣 4 分。

注意这里是按使用节点的种类数计算扣分,与使用次数无关。例如多次使用比较节点,只会扣除 4 分;又如同时使用了比较节点和乘法节点,即使各只使用了一次,也会扣除 8 分。

一个测试点至多被扣到 0 分,即使分数不够扣除,也不会出现负数。

如何测试你的输出

在终端中先切换到该试题的目录下:(windows用户请使用cmd)(假设你把输入输出文件、checker 什么的都放在了 nodes 这个文件夹下)

cd nodes

我们提供checker这个工具来测试你的输出文件是否是可接受的。使用这个工具的方法是,在终端中运行

./checker_linux64 <case_no>

其中case_no是测试数据的编号。例如

./checker_linux64 3

将测试 nodes3.out 是否可以接受。(windows用户请使用checker_win32 3)(什么你是windows 64位?放心吧可以运行win32应用程序的。)

当然我们有对应的 linux 32 位版本:checker_linux32。如果 linux 用户发现无法运行程序,请尝试执行 chmod +x checker_linux64chmod +x checker_linux32 后重试。

其它操作系统请安装 node.js 然后使用 node checker.js <case_no> 运行checker。

在你调用这个程序后,checker 将根据你给出的输出文件给出测试的结果。

另外,你还可以在终端中使用命令

./checker –f <file_name>

来运行 <file_name> 表示的计算机,并通过终端进行交互。

注意: checker 测试你构造的计算机时,使用的数据跟最终测试时可能不同。

My Code

nodes1.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, char* c){
    printf("C %d %s\n", x, c);
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int main(){
    freopen("nodes1.out", "w", stdout);
    int a = In(), b = In();
    a = add(a, b);
    a = lsh(a, 1);
    a = neg(a);
    Out(a);
    return 0;
}

nodes2.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, char* c){
    printf("C %d %s\n", x, c);
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int main(){
    freopen("nodes2.out", "w", stdout);
    int a = In();
    int b = a;
    a = lsh(a, 4);
    a = add(a, b);
    a = neg(a);
    Out(sig(a));
    return 0;
}

nodes3.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, char* c){
    printf("C %d %s\n", x, c);
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int main(){
    freopen("nodes3.out", "w", stdout);
    int a = In();
    a = lsh(a, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    Out(a);
    return 0;
}

nodes4.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int main(){
    freopen("nodes4.out", "w", stdout);
    int a = In();
    Out(Abs(a));
    return 0;
}

nodes5.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int a[50];
int turn10(int *a){
    int ret = add(a[0], lsh(a[1], 1));
    for(int i = 2; i <= 31; i ++){
        ret = add(ret, lsh(a[i], i));
    }
    return ret;
}
int main(){
    freopen("nodes5.out", "w", stdout);
    for(int i = 31; i >= 0; i --){
        a[i] = In();
    }
    Out(turn10(a));
    return 0;
}

nodes6.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, long long c){
    printf("C %d %lld\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int a[50];
int turn10(int *a){
    int ret = add(a[0], lsh(a[1], 1));
    for(int i = 2; i <= 31; i ++){
        ret = add(ret, lsh(a[i], i));
    }
    return ret;
}
void turn2(int x, int *a){
    x = lsh(x, 500);
    for(int i = 31; i >= 1; i --){
        int tmp = addc(x, (-pow(2, i) + 0.01) * pow(2, 500));
        tmp = sig(tmp);
        a[i] = tmp;
        tmp = neg(lsh(tmp, 500 + i));
        x = add(x, tmp);
    }
    a[0] = rsh(x, 500);
}
int main(){
    freopen("nodes6.out", "w", stdout);
    int x = In();
    turn2(x, a);
    for(int i = 31; i >= 0; i --) Out(a[i]);
    return 0;
}

nodes7.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, long long c){
    printf("C %d %lld\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int a[50], b[50];
int turn10(int *a){
    int ret = add(a[0], lsh(a[1], 1));
    for(int i = 2; i <= 31; i ++){
        ret = add(ret, lsh(a[i], i));
    }
    return ret;
}
void turn2(int x, int *a){
    x = lsh(x, 500);
    for(int i = 31; i >= 1; i --){
        int tmp = addc(x, (-pow(2, i) + 0.01) * pow(2, 500));
        tmp = sig(tmp);
        a[i] = tmp;
        tmp = neg(lsh(tmp, 500 + i));
        x = add(x, tmp);
    }
    a[0] = rsh(x, 500);
}
int xor1(int x, int y){
    int a = add(x, y);
    int b = addc(a, -1.5);
    b = neg(p(b));
    b = lsh(b, 1);
    return add(a, b);
}
void xor32(int *a, int *b){
    for(int i = 0; i <= 31; i ++) a[i] = xor1(a[i], b[i]);
}
int main(){
    freopen("nodes7.out", "w", stdout);
    int x = In(); int y = In();
    turn2(x, a); turn2(y, b);
    xor32(a, b); Out(turn10(a));
    return 0;
}

nodes8.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, long long c){
    printf("C %d %lld\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int a[50], b[50];
int turn10(int *a){
    int ret = add(a[0], lsh(a[1], 1));
    for(int i = 2; i <= 31; i ++){
        ret = add(ret, lsh(a[i], i));
    }
    return ret;
}
void turn2(int x, int *a){
    x = lsh(x, 500);
    for(int i = 31; i >= 1; i --){
        int tmp = addc(x, (-pow(2, i) + 0.01) * pow(2, 500));
        tmp = sig(tmp);
        a[i] = tmp;
        tmp = neg(lsh(tmp, 500 + i));
        x = add(x, tmp);
    }
    a[0] = rsh(x, 500);
}
int xor1(int x, int y){
    int a = add(x, y);
    int b = addc(a, -1.5);
    b = neg(p(b));
    b = lsh(b, 1);
    return add(a, b);
}
void xor32(int *a, int *b){
    for(int i = 0; i <= 31; i ++) a[i] = xor1(a[i], b[i]);
}
int div10(int x){
    string a = "2.06343706889556054705";
    string sa = "-0.887298334620741688550198422716226773933599412474263948504833186119911079463425709202638465";    
    return lsh(addc(sig(addc(rsh(x, 150), a)), sa), 150);
}
int main(){
    freopen("nodes8.out", "w", stdout);
    int x = In();
    Out(div10(x));
    return 0;
}

nodes9.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, long long c){
    printf("C %d %lld\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int min0(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 151);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); b = neg(b);
    d = lsh(d, 152); d = add(d, b);
    return d;
}
int a[50], b[50];
int turn10(int *a){
    int ret = add(a[0], lsh(a[1], 1));
    for(int i = 2; i <= 31; i ++){
        ret = add(ret, lsh(a[i], i));
    }
    return ret;
}
void turn2(int x, int *a){
    x = lsh(x, 500);
    for(int i = 31; i >= 1; i --){
        int tmp = addc(x, (-pow(2, i) + 0.01) * pow(2, 500));
        tmp = sig(tmp);
        a[i] = tmp;
        tmp = neg(lsh(tmp, 500 + i));
        x = add(x, tmp);
    }
    a[0] = rsh(x, 500);
}
int xor1(int x, int y){
    int a = add(x, y);
    int b = addc(a, -1.5);
    b = neg(p(b));
    b = lsh(b, 1);
    return add(a, b);
}
void xor32(int *a, int *b){
    for(int i = 0; i <= 31; i ++) a[i] = xor1(a[i], b[i]);
}
int div10(int x){
    string a = "2.06343706889556054705";
    string sa = "-0.887298334620741688550198422716226773933599412474263948504833186119911079463425709202638465";    
    return lsh(addc(sig(addc(rsh(x, 150), a)), sa), 150);
}
int main(){
    freopen("nodes9.out", "w", stdout);
    for(int i = 1; i <= 16; i ++){
        a[i] = In();
    }
    for(int i = 1; i < 16; i ++){
        for(int j = i + 1; j <= 16; j ++){
            int t = add(a[i], a[j]);
            a[i] = add(a[i], min0(add(neg(a[i]), a[j])));
            a[j] = add(t, neg(a[i]));
        }
    }
    for(int i = 1; i <= 16; i ++){
        Out(a[i]);
    }
    return 0;
}

nodes10.cpp

#include <bits/stdc++.h>

using namespace std;
int tot;

int In(){
    printf("I\n");
    return ++tot;
}
int Out(int x){
    printf("O %d\n", x);
    return ++tot;
}
int add(int x, int y){
    printf("+ %d %d\n", x, y);
    return ++tot;
}
int addc(int x, int c){
    printf("C %d %d\n", x, c);
    return ++tot;
}
int addc(int x, long long c){
    printf("C %d %lld\n", x, c);
    return ++tot;
}
int addc(int x, double c){
    printf("C %d %.10lf\n", x, c);
    return ++tot;
}
int addc(int x, string c){
    printf("C %d %s\n", x, c.c_str());
    return ++tot;
}
int neg(int x){
    printf("- %d\n", x);
    return ++tot;
}
int lsh(int x, int c){
    printf("< %d %d\n", x, c);
    return ++tot;
}
int rsh(int x, int c){
    printf("> %d %d\n", x, c);
    return ++tot;
}
int sig(int x){
    printf("S %d\n", x);
    return ++tot;
}

int sgn(int x){
    int a = lsh(x, 500);
    a = sig(a);
    a = lsh(a, 1);
    a = addc(a, -1);
    return a;
}
int p(int x){
    return sig(lsh(x, 500));
}
int Abs(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 152);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); d = neg(d);
    d = lsh(d, 153); d = add(d, b);
    return add(x, d);
}
int min0(int x){
    int b = lsh(p(addc(x, "0.00000000000000000000001")), 151);
    int c = rsh(x, 150);
    int d = sig(add(c, b));
    d = addc(d, -0.5); b = neg(b);
    d = lsh(d, 152); d = add(d, b);
    return d;
}
int max0(int x, int y, int c){
    x = neg(x);
    int b = lsh(p(x), 151);
    int d = sig(add(c, b));
    d = addc(d, -0.5); b = neg(b);
    d = lsh(d, 152); d = add(d, b);
    return d;
}
int a[50], b[50];
int turn10(int *a){
    int ret = add(a[0], lsh(a[1], 1));
    for(int i = 2; i <= 31; i ++){
        ret = add(ret, lsh(a[i], i));
    }
    return ret;
}
void turn2(int x, int *a){
    x = lsh(x, 500);
    for(int i = 31; i >= 1; i --){
        int tmp = addc(x, (-pow(2, i) + 0.01) * pow(2, 500));
        tmp = sig(tmp);
        a[i] = tmp;
        tmp = neg(lsh(tmp, 500 + i));
        x = add(x, tmp);
    }
    a[0] = rsh(x, 500);
}
int xor1(int x, int y){
    int a = add(x, y);
    int b = addc(a, -1.5);
    b = neg(p(b));
    b = lsh(b, 1);
    return add(a, b);
}
void xor32(int *a, int *b){
    for(int i = 0; i <= 31; i ++) a[i] = xor1(a[i], b[i]);
}
int div10(int x){
    string a = "2.06343706889556054705";
    string sa = "-0.887298334620741688550198422716226773933599412474263948504833186119911079463425709202638465";    
    return lsh(addc(sig(addc(rsh(x, 150), a)), sa), 150);
}
int modadd(int x, int y, int cc, int rshc, int negc){
    int s = add(x, y);
    int tmp = add(s, cc);
    return add(s, max0(tmp, negc, rshc));
}
int main(){
    freopen("nodes10.out", "w", stdout);
    int x = In(); int y = In(); int c = In(); int negc = neg(c); int rshc = rsh(negc, 150); int cc = addc(negc, "0.0000001");
    turn2(x, a);
    x = rsh(x, 1000);
    for(int i = 31; i >= 0; i --){
        x = add(x, x);
        x = modadd(x, a[i], cc, rshc, negc);
    }
    turn2(y, b);
    int d = x; x = rsh(x, 1000);
    for(int i = 31; i >= 0; i --){
        x = modadd(x, x, cc, rshc, negc);
        x = modadd(x, max0(addc(b[i], "-0.5"), d, rsh(d, 150)), cc, rshc,negc);
    }
    Out(x);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值