• Codeforces Round #421 (Div. 1) 题解


    B.Mister B and PR Shifts

    分类讨论一下就好了。

    #include <bits/stdc++.h>
    #define for1(a,b,i) for(int i=a;i<=b;++i)
    #define FOR2(a,b,i) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    
    #define M 1000005
    int n;
    int a[M];
    ll sum[M],index_[M];
    
    inline void add_(int l,int r,int x,int opt) {
        sum[l]+=x,sum[r+1]-=x;
        index_[l]+=opt,index_[r+1]-=opt;
    }
    
    int main () {
        scanf("%d",&n);
        for1(1,n,i) scanf("%d",a+i);
        for1(1,n,i) {
            if(a[i]>i) {
                int l=0,r=a[i]-i;
                
                if(l<=r) add_(l,r,a[i]-i,-1);
                
                l=r+1,r=n-i;
                if(l<=r) add_(l,r,i-a[i],1);
                
                l=r+1,r=n-1;
                if(l<=r) add_(l,r,a[i]-i+n,-1);
            }
            else {
                int l=0,r=n-i;
                
                if(l<=r) add_(l,r,i-a[i],1);
                
                l=r+1,r=min(a[i]+n-i,n-1);
                if(l<=r) add_(l,r,a[i]-i+n,-1);
                
                l=r+1,r=n-1;
                if(l<=r) add_(l,r,i-n-a[i],1);
            }
        }
        for1(1,n-1,i) {
            index_[i]+=index_[i-1];
            sum[i]+=sum[i-1];
        }
        for1(1,n-1,i) sum[i]+=i*index_[i];
        
        int ans=0;
        for1(1,n-1,i) if(sum[i]<sum[ans]) ans=i;
        printf("%lld %d
    ",sum[ans],ans);
    }
    View Code

    C.Mister B and Beacons on Field

    容易推出答案就是$sum_{d|2S}[d<=n]+sum_{i=1}^{m}2S|gcd(i,n)$

    $2S$的因子个数很好搞,直接分解完枚举所有因子就行了,$1e5$级别的。

    考虑怎么求第二个式子。

    考虑对于$p$,若$cnt_n[p]>cnt_2S[p]$,才有可能使得不满足条件。

    直接把所有的$p$都找出来容斥一发就行了。

    感觉自己的代码真的丑,看了一发别人的代码,还是$STL$好用啊,学会正确使用$STL$。

    #include <bits/stdc++.h>
    #define for1(a,b,i) for(int i=a;i<=b;++i)
    #define FOR2(a,b,i) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    
    #define M 1100005
    ll n,m,S,ans;
    int a[3],b[3],s[3];
    
    vector <ll> cc;
    map <int,int> sp,np;
    
    inline void trans_(map<int,int>::iterator x,ll sum) {
        if(sum>n) return;
        if(x==sp.end()) return ++ans,void();
        ll now=1;
        auto it=x; it++;
        for1(0,x->second,i) {
            trans_(it,sum*now);
            now*=x->first;
        }
    }
    
    int main () {
        //freopen("a.in","r",stdin);
        int Test_;
        scanf("%d",&Test_);
        while (Test_--) {
            ans=0;
            n=m=1,S=2;
            sp.clear(),np.clear(),cc.clear();
            scanf("%d%d%d%d%d%d%d%d%d",a,a+1,a+2,b,b+1,b+2,s,s+1,s+2);
            n=n*a[0]*a[1]*a[2],m=m*b[0]*b[1]*b[2],S=S*s[0]*s[1]*s[2];
            
            sp[2]=1;
            for1(2,1000,i) {
                for1(0,2,j) while (a[j]%i==0) 
                    a[j]/=i,++np[i];
                for1(0,2,j) while (s[j]%i==0) 
                    s[j]/=i,++sp[i];
            }
            for1(0,2,i) if(a[i]>1) ++np[a[i]];
            for1(0,2,i) if(s[i]>1) ++sp[s[i]];
            
            trans_(sp.begin(),1);
            
            for(auto i=np.begin();i!=np.end();i++) 
                if(sp[i->first]<i->second) {
                    ll x=1;
                    FOR2(sp[i->first]+1,1,j) x=x*i->first;
                    cc.push_back(x);
                }
            
            int size=cc.size();
            FOR2((1<<size)-1,0,i) {
                ll x=m;
                int opt=1;
                for1(1,size,j) if(i>>j-1&1) opt*=-1,x/=cc[j-1];
                ans+=opt*x;
            }
            
            printf("%lld
    ",ans);
        }
    }
    View Code

    D.Mister B and Astronomers

    首先显然可以分成$T/gcd(T,sum)$类。

    对于不同类别之间不相互影响。

    对于同类的我们可以算出$g[i]$代表$(sum[1]+g[i]*T) mod T == sum[i]$。

    又因为每个人可以得到的是一个前缀(显然可以证明)。

    然后直接用个$set$查个后继就行了。

    #include <bits/stdc++.h>
    #define for1(a,b,i) for(int i=a;i<=b;++i)
    #define FOR2(a,b,i) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    inline int read () {
        int f=1,sum=0;
        char x=getchar();
        for(;(x<'0'||x>'9');x=getchar()) if(x=='-') f=-1;
        for(;x>='0'&&x<='9';x=getchar()) sum=sum*10+x-'0';
        return f*sum;
    }
    
    #define M 200005
    int T,n;
    int GCD,x_,y_,num;
    int a[M],f[M],g[M],id[M],sum[M],ans[M];
    
    multiset <int> cc;
    map <int,bool> vis;
    
    inline bool comp(int x,int y) {return f[x]==f[y]?x<y:f[x]<f[y];}
    
    inline int ex_gcd(int a,int b,int &x,int &y) {
        if(!b) return x=1,y=0,a;
        int d=ex_gcd(b,a%b,x,y);
        int t=x;
        x=y;
        y=t-(a/b)*y;
        return d;
    }
    
    inline int calc_(int x) {
        if(vis.count(g[x])) return 0;
        if(!cc.size()) return num;
        int c=(g[x]+1)%num;
        auto it=cc.lower_bound(c);
        if(it==cc.end()) it=cc.begin();
        //cout<<x<<" "<<*it<<" "<<g[x]<<endl;
        return *it-g[x]+(g[x]>=*it)*num;
    }
    
    int main () {
        //freopen("a.in","r",stdin);
        T=read(),n=read();
        for1(1,n,i) {
            a[i]=read();
            sum[0]=(sum[0]+a[i])%T;
            if(i>1) sum[i]=(sum[i-1]+a[i])%T;
        }
        GCD=ex_gcd(sum[0],T,x_,y_);
        num=T/GCD;
        if(x_<0) x_+=((-x_-1)/num+1)*num;
        if(x_>0) x_-=(x_-1)/num*num;
        
        for1(1,n,i) {
            f[i]=sum[i];
            f[i]=min(f[i],(sum[i]+((T-sum[i]-1)/GCD+1)*GCD)%T);
        }
        for1(1,n,i) id[i]=i;
        sort(id+1,id+n+1,comp);
        for(int l=1,r;l<=n;l=r+1) {
            r=l;
            while (r<n&&f[id[l]]==f[id[r+1]]) ++r;
            int cnt=r-l+1;
            for1(1,cnt,i) {
                int x=id[i+l-1];
                int c=sum[x]-sum[id[l]];
                if(c>=0) g[i]=1ll*c/GCD*x_%num;
                else g[i]=1ll*(c+T)/GCD*x_%num;
                cc.insert(g[i]);
            }
            for1(1,cnt,i) {
                cc.erase(cc.lower_bound(g[i]));
                ans[id[i+l-1]]=calc_(i);
                cc.insert(g[i]);
                vis[g[i]]=1;
            }
            cc.clear(),vis.clear();
        }
        for1(1,n,i) printf("%d ",ans[i]);
        puts("");
    }
    View Code

    E.Mister B and Flight to the moon

    按照$mod4$分类讨论就行了。

    #include <bits/stdc++.h>
    #define for1(a,b,i) for(int i=a;i<=b;++i)
    #define FOR2(a,b,i) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    
    #define M 305
    int n;
    int e_size;
    
    struct node {
        int size,a,b,c,d;
    }e[M*M];
    
    int main () {
        //freopen("a.in","r",stdin);
        scanf("%d",&n);
        if(n<=2) return puts("-1"),0;
        if(n==3) {
            puts("2");
            puts("3 1 2 3");
            puts("3 1 2 3");
            return 0;
        }
        if(n%4==0) {
            for(int i=1;i<=n;i+=4) {
                int a=i,b=i+1,c=i+2,d=i+3;
                e[++e_size]=(node){3,a,b,c};
                e[++e_size]=(node){3,a,c,d};
                e[++e_size]=(node){3,c,d,b};
                e[++e_size]=(node){3,d,b,a};
            }
            for(int i=1;i<=n;i+=2) {
                int x=i,y=i+1;
                for(int j=i+2+(i%4==1)*2;j<=n;j+=2) {
                    int a=j,b=j+1;
                    e[++e_size]=(node){4,x,a,y,b};
                    e[++e_size]=(node){4,x,a,y,b};
                }
            }
        }
        else if(n%4==1) {
            --n;
            for(int i=1;i<=n;i+=2) {
                int x=i,y=i+1;
                for(int j=i+2;j<=n;j+=2) {
                    int a=j,b=j+1;
                    e[++e_size]=(node){4,x,a,y,b};
                    e[++e_size]=(node){4,x,a,y,b};
                }
                e[++e_size]=(node){3,x,y,n+1};
                e[++e_size]=(node){3,x,y,n+1};
            }
        }
        else if(n%4==2) {
            n-=2;
            for(int i=1;i<=n;i+=2) {
                int x=i,y=i+1;
                for(int j=i+2;j<=n;j+=2) {
                    int a=j,b=j+1;
                    e[++e_size]=(node){4,x,a,y,b};
                    e[++e_size]=(node){4,x,a,y,b};
                }
                if(i==1) {
                    e[++e_size]=(node){3,x,n+1,n+2};
                    e[++e_size]=(node){3,n+1,n+2,y};
                    e[++e_size]=(node){3,n+2,y,x};
                    e[++e_size]=(node){3,y,x,n+1};
                }
                else {
                    e[++e_size]=(node){3,x,y,n+2};
                    e[++e_size]=(node){3,y,x,n+1};
                    e[++e_size]=(node){4,x,n+1,y,n+2};
                }
            }
        }
        else {
            n-=3;
            e[++e_size]=(node){3,n+1,n+2,n+3};
            e[++e_size]=(node){3,n+1,n+2,n+3};
            for(int i=1;i<=n;i+=2) {
                int x=i,y=i+1;
                for(int j=i+2;j<=n;j+=2) {
                    int a=j,b=j+1;
                    e[++e_size]=(node){4,x,a,y,b};
                    e[++e_size]=(node){4,x,a,y,b};
                }
                
                e[++e_size]=(node){4,x,n+1,y,n+2};
                e[++e_size]=(node){4,x,n+1,y,n+2};
                
                e[++e_size]=(node){3,x,y,n+3};
                e[++e_size]=(node){3,x,y,n+3};
            }
        }
        
        printf("%d
    ",e_size);
        for1(1,e_size,i) { 
            printf("%d %d %d %d",e[i].size,e[i].a,e[i].b,e[i].c);
            if(e[i].size==4) printf(" %d
    ",e[i].d);
            else printf("
    ");
        }
    }
    View Code
  • 相关阅读:
    对于软件工程这门课程的一些心得
    第一次冲刺(10)
    第一次冲刺(7~9)
    第一次冲刺(6)
    第一次冲刺(5)
    第一次冲刺(4)
    第一次冲刺(3)
    第一次冲刺(2)
    Arrays.asList 为什么不能 add 或者 remove 而 ArrayList 可以
    Javascript保证精度的小数乘法
  • 原文地址:https://www.cnblogs.com/asd123www/p/9787037.html
Copyright © 2020-2023  润新知