话说我怎么觉得我没咕多长时间啊,怎么就又落了20多场题解啊
T1 array:
根据题意不难列出二元一次方程,于是可以用exgcd求解,然而还有一个限制条件就是$abs(x)+abs(y)$最小,这好像很难搞,但是我们用exgcd求出一组特解之后的通解公式是个一次函数,通过手玩可知x,y只可能是最小正整数或最大负整数解,这就很好整,时间复杂度$O(n)$,当然也可以三分。
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int N=1e5+10; 5 void exgcd(int a,int b,int &x,int &y,int &gcd){//ax+by=c,gcd wei gongyueshu 6 if(!b){ 7 gcd=a; 8 x=1; 9 y=0; 10 } 11 else{ 12 exgcd(b,a%b,y,x,gcd); 13 y-=a/b*x; 14 } 15 } 16 int gcd(int a,int b){ 17 return (!b)?a:gcd(b,a%b); 18 } 19 int solve(int a,int b,int x,int y,int k,int g){ 20 //cout<<"a=="<<a<<" b=="<<b<<" k=="<<k<<endl; 21 int ka=a,kb=b; 22 a/=g,b/=g;k/=g; 23 //cout<<"a=="<<a<<" b=="<<b<<" k=="<<k<<endl; 24 int res=0x7fffffffffffffff; 25 int tmpx=x%b,tmpy=(k-a*tmpx)/b; 26 res=min(res,abs(tmpx)+abs(tmpy)); 27 //cout<<"tmpx=="<<tmpx<<" tmpy=="<<tmpy<<" res=="<<res<<endl; 28 if(tmpx==0){ 29 res=min(res,abs(tmpx+b)+abs(tmpy-a)); 30 res=min(res,abs(tmpx-b)+abs(tmpy+a)); 31 } 32 33 else if(tmpx<0) tmpx+=b,tmpy-=a,res=min(res,abs(tmpx)+abs(tmpy)); 34 else tmpx-=b,tmpy+=a,res=min(res,abs(tmpx)+abs(tmpy)); 35 //cout<<"tmpx=="<<tmpx<<" tmpy=="<<tmpy<<" res=="<<res<<endl; 36 tmpy=y%a,tmpx=(k-b*tmpy)/a; 37 res=min(res,abs(tmpx)+abs(tmpy)); 38 //cout<<"tmpx=="<<tmpx<<" tmpy=="<<tmpy<<" res=="<<res<<endl; 39 if(tmpy==0){ 40 res=min(res,abs(tmpx+b)+abs(tmpy-a)); 41 res=min(res,abs(tmpx-b)+abs(tmpy+a)); 42 } 43 else if(tmpy<0) tmpy+=a,tmpx-=b,res=min(res,abs(tmpx)+abs(tmpy)); 44 else tmpy-=a,tmpx+=b,res=min(res,abs(tmpx)+abs(tmpy)); 45 //cout<<"tmpx=="<<tmpx<<" tmpy=="<<tmpy<<" res=="<<res<<endl; 46 return res; 47 } 48 int k[N]; 49 main(){ 50 //freopen("1.in","r",stdin); 51 int n,a,b; 52 scanf("%lld%lld%lld",&n,&a,&b); 53 for(int i=1;i<=n;++i) scanf("%lld",&k[i]); 54 int flag=0; 55 long long ans=0; 56 int x,y; 57 int g; 58 exgcd(a,b,x,y,g); 59 int tmpx=x,tmpy=y; 60 for(int i=1;i<=n;++i){ 61 //cout<<"x=="<< x<<" y=="<<y<<endl; 62 //cout<<"gcd=="<<g<<" k[i]=="<<k[i]<<endl; 63 if(k[i]%g!=0) {flag=1;break;} 64 int tmp=k[i]/g; 65 x=tmpx*tmp,y=tmpy*tmp; 66 //cout<<"x=="<<x<<" y=="<<y<<endl; 67 int res=solve(a,b,x,y,k[i],g); 68 //cout<<"res=="<<res<<endl; 69 ans+=res; 70 } 71 if(flag) puts("-1"); 72 else printf("%lld\n",ans); 73 return 0; 74 }