题面
由于不知道
A
,
B
A,B
A,B,且操作总数的限制,需要用类似快速乘的方式,将
A
,
B
A,B
A,B 拆为
log
2
A
\log_2A
log2A 个二进制位,最后进行卷积即可。
首先要召唤出一个
1
1
1。只要让
A
A
A 与
A
+
B
A+B
A+B 比较即可。当
A
,
B
A,B
A,B 有一个为
0
0
0 时,再或一个
B
B
B 与
A
+
B
A+B
A+B 比较即可。当
A
=
B
=
0
A=B=0
A=B=0 时无法召唤出
1
1
1且不需要
1
1
1。
有了
1
1
1之后,就可以倍增得到所有
2
i
2^i
2i 的值。记录变量
c
c
c 表示当前拆出来的二进制位之和。每次让
c
+
2
i
c+2^i
c+2i 与
A
A
A 比较,可以得到
A
A
A 的第
i
i
i 位。然后将结果倍增
i
i
i 次,加到
c
c
c 上即可。由于最终得到的是
A
−
1
A-1
A−1 的二进制位,所以在最开始让
A
,
B
A,B
A,B 都加上
1
1
1即可。
做卷积可以通过加和与运算来实现,最后用倍增的方式累加到答案上即可。
时空复杂度
O
(
log
2
2
A
)
O(\log_2^2 A)
O(log22A)
#include<stdio.h>
#include<vector>
using namespace std;
#define R register int
#define N 199999
struct Operate{
char Opt;
int A,B,C;
};
inline Operate Pair(char a,int b,int c,int d){
Operate res;
res.Opt=a;
res.A=b;
res.B=c;
res.C=d;
return res;
}
int main(){
vector<Operate>Q;
Q.push_back(Pair('+',0,1,N-31));
Q.push_back(Pair('<',0,N-31,N));
Q.push_back(Pair('<',1,N-31,N-33));
Q.push_back(Pair('+',N-33,N,N-31));
Q.push_back(Pair('<',N-30,N-31,N));
Q.push_back(Pair('+',0,N,0));
Q.push_back(Pair('+',1,N,1));
for(R i=1;i!=30;i++){
Q.push_back(Pair('+',N-i+1,N-i+1,N-i));
}
for(R i=29;i!=-1;i--){
Q.push_back(Pair('+',N-32,N-i,N-31));
Q.push_back(Pair('<',N-31,0,i+3));
Q.push_back(Pair('+',i+3,N-30,N-31));
for(R j=i;j!=0;j--){
Q.push_back(Pair('+',N-31,N-31,N-31));
}
Q.push_back(Pair('+',N-31,N-32,N-32));
}
Q.push_back(Pair('+',N-30,N-30,N-32));
for(R i=29;i!=-1;i--){
Q.push_back(Pair('+',N-32,N-i,N-31));
Q.push_back(Pair('<',N-31,1,i+33));
Q.push_back(Pair('+',i+33,N-30,N-31));
for(R j=i;j!=0;j--){
Q.push_back(Pair('+',N-31,N-31,N-31));
}
Q.push_back(Pair('+',N-31,N-32,N-32));
}
for(R i=0;i!=30;i++){
for(R j=0;j!=30;j++){
Q.push_back(Pair('+',i+3,j+33,N-31));
Q.push_back(Pair('<',N,N-31,N-31));
Q.push_back(Pair('+',N-31,i+j+65,i+j+65));
}
}
for(R i=65;i!=124;i++){
for(R j=i;j!=65;j--){
Q.push_back(Pair('+',i,i,i));
}
Q.push_back(Pair('+',2,i,2));
}
printf("%d",Q.size());
for(vector<Operate>::iterator T=Q.begin();T!=Q.end();T++){
printf("\n%c ",T->Opt);
printf("%d %d %d",T->A,T->B,T->C);
}
return 0;
}