CodeForces 1427E Xum
我们考虑每次消掉当前数上最高的 \(1\)。
假设当前这个数的二进制表示为 1abcd1
,这里中间有几位无所谓,方法大致是相同的。abcd
代表一个 \(01\) 串。
我们依次产生如下的数:
0000001abcd1
01abcd100000
01abcd0abcd1
1abcd01abcd1
1abcd0000000
1abcd1000000
000001000000
000000100000
(倒数第二个数通过自增和异或第二个数把第二个数除最后一个 \(1\) 的所有 \(1\) 消掉就得到了这个)
这里每个数都可以用前面的数进行运算得到,最后只需用最后一个数异或当前数即可消掉最高位的 \(1\)。
AC code:
#include<bits/stdc++.h>
#define int long long
#define N 2005
#define mod 1000000007
#define pii pair<int,int>
#define x first
//#define y second
using namespace std;
int T=1,n;
struct node{
int a,b;
char c;
};
void solve(int cs){
cin>>n;
vector<node>res;
for(int i=19;i;i--){
if(n>>i&1){
int x=n;
for(int j=0;j<i;j++){
res.push_back({x,x,'+'});
x<<=1;
}
int y=(x^n);
res.push_back({x,n,'^'});
int z=x+y;
res.push_back({x,y,'+'});
int w=(z^n);
res.push_back({z,n,'^'});
int t=(x<<1);
res.push_back({x,x,'+'});
int cur=(t^w);
res.push_back({t,w,'^'});
int lim=1<<i;
while(x>lim){
if(!(x&cur)){
res.push_back({cur,cur,'+'});
cur<<=1;
continue;
}
res.push_back({x,cur,'^'});
x^=cur;
res.push_back({cur,cur,'+'});
cur<<=1;
}
res.push_back({n,x,'^'});
n^=x;
}
}
cout<<res.size()<<'\n';
for(auto it:res){
cout<<it.a<<' '<<it.c<<' '<<it.b<<'\n';
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cin>>T;
// init();
for(int cs=1;cs<=T;cs++){
solve(cs);
}
return 0;
}