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
原文地址:https://www.cnblogs.com/asd123www/p/9787037.html