【模拟】分类讨论大模拟+数论——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';
        }
    }


} 

 

posted on 2020-05-28 15:16  zsben  阅读(182)  评论(0编辑  收藏  举报

导航