[cf1427E]Xum

假设$x$的最高位为$2^{t}$(即$2^{t}\le x<2^{t+1}$),并构造出$y=2^{t}x\oplus x$,不难发现两者仅在第$t$位上均为1,那么根据异或的性质可得$y=(2^{t}+1)x-2^{t+1}$

由于$x$为奇数,即$(x,2^{t+1})=1$,进而也即$(x,y)=1$

通过扩欧求出一组$ax+by=1$的解,并调整使得$0<a\le 2y$且$a\equiv 1(mod\ 2)$,对应的$-2x\le b<0$,根据奇偶性可得$ax$为奇数(且$by$为偶数),那么$ax+by=1$即等价于$ax\oplus (-b)y=1$,由此计算可得

另外,计算过程中需要实现乘法,这借助类似快速幂的做法实现即可

最终操作次数(和时间复杂度)约为$o(\log n)$,数字范围约为$2n^{3}$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 struct Data{
 5     int p;
 6     ll x,y;
 7 };
 8 vector<Data>ans;
 9 ll n,m,x,y;
10 void calc(ll n,ll m){
11     m--;
12     ll s=n,sum=n;
13     while (m){
14         if (m&1){
15             ans.push_back(Data{1,s,sum});
16             sum+=s;
17         }
18         ans.push_back(Data{1,s,s});
19         s<<=1,m>>=1;
20     }
21 }
22 void exgcd(ll a,ll b,ll &x,ll &y){
23     if (!b){
24         x=1,y=0;
25         return;
26     }
27     exgcd(b,a%b,y,x);
28     y-=(a/b)*x;
29 }
30 int main(){
31     scanf("%lld",&n);
32     ll t=2;
33     while ((t<<1)<=n)t<<=1;
34     calc(n,t);
35     m=((n*t)^n),ans.push_back(Data{0,n*t,n});
36     exgcd(n,m,x,y);
37     x=(x%m+m)%m;
38     if (x%2==0)x+=m;
39     y=(n*x-1)/m;
40     calc(n,x),calc(m,y);
41     ans.push_back(Data{0,n*x,m*y});
42     printf("%d\n",(int)ans.size());
43     for(int i=0;i<ans.size();i++)
44         if (ans[i].p)printf("%lld + %lld\n",ans[i].x,ans[i].y);
45         else printf("%lld ^ %lld\n",ans[i].x,ans[i].y);
46     return 0;
47 }
View Code

 

posted @ 2021-10-11 12:56  PYWBKTDA  阅读(50)  评论(0编辑  收藏  举报