【模拟】分类讨论大模拟+数论——cf1358F
写吐了。。
/* n=1:直接判定是否相等 n=2:判定能否从(b1,b2)变成(a1,a2) 由于暴力会t,所以改为取模(由取模向前回退操作是可以证明正确性的) 因为b2=a1+a2,所以对于b2来说一定经历了一连串的P操作,这一连串P操作的回退可以直接用b2%b1来代替 n>=3: 暴力模拟从b退回a 显然每一步的b都必须是单调的 如果b单调递增:那么直接退一步 反之b->R(b),再退一步 由于n>=3,所以跑的退数不会很多 */ #include<bits/stdc++.h> using namespace std; #define N 500005 #define ll long long ll n,a[N],b[N]; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)cin>>b[i]; if(n==1){ if(a[1]==b[1])cout<<"SMALL"<<'\n'<<0; else cout<<"IMPOSSIBLE"; return 0; } if(n==2){ vector<pair<ll,ll> >ans; while(true){ // 不断取模,保证op2最少 if(b[1]==0 || b[2]==0){puts("IMPOSSIBLE");return 0;} if(a[1]==b[1] && a[2]==b[2])break; if(a[2]==b[1] && a[1]==b[2]){ans.emplace_back(1,1); break;} if(b[1]==b[2]){puts("IMPOSSIBLE");return 0;} if(b[1]>b[2]){ans.emplace_back(1,1);swap(b[1],b[2]);} if(a[1]==b[1] && a[2]<b[2] && a[2]%b[1]==b[2]%b[1]){ ans.emplace_back((b[2]-a[2])/b[1],2);break; } if(a[2]==b[1] && a[1]<b[2] && a[1]%b[1]==b[2]%b[1]){ ans.emplace_back((b[2]-a[1])/b[1],2); ans.emplace_back(1,1);break; } ans.emplace_back(b[2]/b[1],2); b[2]%=b[1]; } ll sum=0,s2=0; for(auto p:ans) if(p.second==2)sum+=p.first; else s2+=p.first; if(sum<=2e5){ cout<<"SMALL\n"<<sum+s2<<'\n'; for(int i=ans.size()-1;i>=0;i--){ auto p=ans[i]; for(int i=1;i<=p.first;i++){ if(p.second==1)cout<<'R'; else cout<<'P'; } } }else { cout<<"BIG\n"<<sum; } return 0; } vector<int>ans; int tot=0; while(true){ int f=0; for(int i=1;i<=n;i++) if(a[i]!=b[i]){f=1;break;} if(!f)break; f=0; int i=1,j=n; while(i<j)swap(b[i],b[j]),++i,--j; for(int i=1;i<=n;i++) if(a[i]!=b[i]){f=1;break;} if(!f){ ans.push_back(1); break; }else { int i=1,j=n; while(i<j)swap(b[i],b[j]),++i,--j; } int f1=0,f2=0; for(int i=1;i<n;i++){ if(b[i]==b[i+1]){puts("IMPOSSIBLE");return 0;} if(b[i]>b[i+1])f1=1; else f2=1; } if(f1 && f2){puts("IMPOSSIBLE");return 0;} if(f1){ int i=1,j=n; while(i<j)swap(b[i],b[j]),++i,--j; ans.push_back(1); } for(int i=n;i>=1;i--)b[i]-=b[i-1]; ans.push_back(2); tot++; } int f=0; for(int i=1;i<=n;i++) if(a[i]!=b[i]){f=1;break;} if(!f){ if(tot<=2e5){ cout<<"SMALL\n"<<ans.size()<<'\n'; for(int i=ans.size()-1;i>=0;i--){ if(ans[i]==1)cout<<"R"; else cout<<"P"; } }else { int t=0; for(auto v:ans) if(v==2)t++; cout<<"BIG\n"<<t<<'\n'; } } }