2018 Multi-University Training Contest 7

1001:Age of Moyu

1002:AraBellaC

 枚举循环周期,对每个循环周期内的mxa,mnb,mxb,mnc二分寻找,要保证(mxa-1)%len<(mnb-1)%len和(mxb-1)%len<(mnc-1)%len。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
#include <iostream>
#include <stack>
#include <set>
#include <map>
using namespace std;

const int MAX=1e5+5;
int t,m;
int a,b,c;
vector<int> E[3];

void update(int aa,int bb,int cc){
    int flag=0;
    if(aa<a) flag=1;
    else if(aa==a&&bb<b) flag=1;
    else if(aa==a&&bb==b&&cc<c) flag=1;
    if(flag) a=aa,b=bb,c=cc;
}

int main(){
    int i,j;
    
    //freopen("data.in","r",stdin);
    scanf("%d",&t);
    while(t--){
        int mx=0;
        a=b=c=0x3f3f3f3f;
        for(i=0;i<3;i++) E[i].clear(),E[i].push_back(0);
        scanf("%d",&m);
        for(i=0;i<m;i++){
            int pos;char c;
            scanf("%d %c",&pos,&c);
            E[c-'A'].push_back(pos);
            mx=max(mx,pos);
        }
        for(i=0;i<3;i++) E[i].push_back(MAX),sort(E[i].begin(),E[i].end());
        for(i=1;i<=mx;i++){
            int mxa=0,mnc=MAX,mxb=0,mnb=MAX;
            for(j=(mx+i-1)/i;j>0;j--){
                int tmp=*(upper_bound(E[0].begin(),E[0].end(),j*i)-1);
                if(tmp>(j-1)*i) mxa=max(mxa,(tmp-1)%i);
                tmp=*upper_bound(E[1].begin(),E[1].end(),(j-1)*i);
                if(tmp<=j*i) mnb=min(mnb,(tmp-1)%i);
                tmp=*(upper_bound(E[1].begin(),E[1].end(),j*i)-1);
                if(tmp>(j-1)*i) mxb=max(mxb,(tmp-1)%i);
                tmp=*upper_bound(E[2].begin(),E[2].end(),(j-1)*i);
                if(tmp<=j*i) mnc=min(mnc,(tmp-1)%i);
                if(mxa>=mnb||mxb>=mnc) break;
            }
            if(j==0) update(mxa+1,mxb-mxa,i-mxb-1);
        }
        if(a==0x3f3f3f3f) puts("NO");
        else printf("%d %d %d\n",a,b,c);
    }
    
    return 0;
} 
View Code

1005:GuGuFishtion

首先推公式,欧拉函数是积性函数但不是一个完全积性函数,所以a,b不互质的情况下肯定还有一个偏移量。然后质因数分解一下a,b可以用数论知识证明差一个GCD(a,b)/Φ(GCD(a,b)),所以对于所有a,b不互质的情况下对答案的贡献是GCD(a,b)/Φ(GCD(a,b)),互质的话贡献是1。然后容斥,枚举k,容斥计算以k作为gcd的数对有多少个,然后乘上贡献就行了。

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N=1000000+5;

LL tmp,ans;
long long n,m,p;
long long phi[N], cnt, prime[N/3],dy[N], val[N], q[N],sum_val[N],sum[N],inv[N],mu[N];
bool com[N];

int primes;
void get_prime_phi(){
   memset( com, false, sizeof( com ) );
    primes = 0;
    phi[1] = 1;
    mu[1] = 1;
    for (int i = 2; i < N; ++i){
        if (!com[i]) {
            prime[primes++] = i;
            phi[i] = i-1;
            mu[i] = -1;
        }
        for (int j = 0; j < primes && i*prime[j] <= N; ++j){
            com[i*prime[j]] = true;
            if (i % prime[j]){
                phi[i*prime[j]] = phi[i]*(prime[j]-1);
                mu[i*prime[j]] = -mu[i];
            }
            else {
                mu[i*prime[j]] = 0;
                phi[i*prime[j]] = phi[i]*prime[j];
                break;
            }
        }
    }
}

int lim;
long long f[N],F[N];

void get(){
    for(int i=1;i<=lim;++i)   F[i]=1ll*(m/i)*(n/i)%p;
    for(int i=lim;i>0;--i){
            f[i]=F[i];
        for(int j=i+i;j<=lim;j+=i)
            f[i]-=1ll*f[j]%p;
    }
    for(int i=1;i<=lim;++i)   f[i]%=p;
}


int main(){
    //freopen("case.in","r",stdin);
    int T;
    scanf("%d",&T);
    get_prime_phi();

    while(T--){
        scanf("%lld%lld%lld",&n,&m,&p); tmp=ans=0;
        lim=min(n,m);
        memset(inv,0,sizeof(inv));
        memset(f,0,sizeof(f));
        inv[1]=1;
        for(register int i=2;i<=lim+2;i++)
            inv[i]=(LL)(p-p/i)*inv[p%i]%p;
        get();

        for(register int i=1;i<=lim;i++){
            val[i]=(LL)i*inv[phi[i]]%p;
            ans=(ans+(LL)val[i]*f[i]%p)%p;
            if(ans<0) ans+=p;
            //cout<<ans<<endl;
        }

        printf("%lld\n",ans);
    }
    return 0;
}
View Code

1006:Lord Li's problem

有意思的dp;
根据异或的性质,X_0⊕X_1⊕X_2⊕X_3⊕…..⊕X_(M-1)=S⊕T 
计算出S⊕T中一共有cnt个1,将这个二进制数标准化,使它成为前面N-cnt个0,后cnt个1的二进制数,答案保持不变,问题变为:用K个N位且有3个1的不同二进制数进行异或,最终得到前面N-cnt个0,后面cnt个1这个二进制数,有多少种方案? 
递推。设d[K][M]表示用K个N位且有3个1的不同二进制数进行异或,最终得到前面N-cnt个0,后面cnt个1这个二进制数的方案数。
然后可以容易推出状态只可以从上一层的-1,-3,+1,+3这些状态转移过来 考虑加入重复串的影响,d[i][j]-= (d[i-2][j] * (C[n][3]-i+2);表示去除加入i-2个数字并且后面有j个1这个二进制数但后来又异或上两个之前没用过的相同的数的方案数, 考虑二进制数加入的先后顺序给答案带来的额外贡献,d[i][j]=d[i][j]*inv[i]%mod
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <map>
using namespace std;
const long long mod=19260817;

long long dp[30][50],c[50][50],inv[110];
char S[45],T[45];
int n,k;

void init()
{
    memset(dp,0,sizeof(dp));
}

int main()
{
    int i,j;
    c[0][0]=1;
    for(i=1;i<=45;i++)
    {
        c[i][0]=c[i][i]=1;
        for(j=1;j<i;j++)
        {
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
        }
    }

    inv[1]=1;
    for(i=2;i<=60;i++)
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;

    int cas=1;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n==0&&k==0) break;
        init();
        scanf("%s%s",S,T);
        int num_1=0;
        for(i=0;i<n;i++)
            if((S[i]-'0')^(T[i]-'0')==1) num_1++;
        dp[0][0]=1;
        for(i=1;i<=k;i++)
        {
            for(j=0;j<=n;j++)
            {
                if(j>=3) dp[i][j]=(dp[i][j]+dp[i-1][j-3]*c[j][3])%mod;
                if(j>=1) dp[i][j]=(dp[i][j]+dp[i-1][j-1]*c[j][2]%mod*c[n-j][1])%mod;
                if(j+3<=n) dp[i][j]=(dp[i][j]+dp[i-1][j+3]*c[n-j][3])%mod;
                if(j+1<=n) dp[i][j]=(dp[i][j] + dp[i - 1][j + 1] * c[j][1] %mod* c[n - j][2]) % mod;
                if (i - 2 >= 0)dp[i][j] = (dp[i][j] - (dp[i - 2][j] * (c[n][3] - i + 2))) % mod;
                dp[i][j] = dp[i][j] * inv[i] % mod;
                if(dp[i][j]<0) dp[i][j]+=mod;
            }
        }
        printf("Case #%d: %lld\n",cas++, dp[k][num_1]);
    }
    return 0;
}
View Code

1007:Reverse Game

1008:Traffic Network in Numazu

1009:

1010:

矩阵快速幂,首先可以看出这题只能用矩阵快速幂,然后考虑对p进行分块,处理出p/i这个矩阵的指数,然后就矩阵快速幂了

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
#include <iostream>
#include <stack>
#include <set>
#include <map>
using namespace std;

const int MAX=5; 
const int mod=1e9+7;

struct Matrix{
    long long mp[MAX][MAX];  //矩阵 
    int n,m;  //行 列 
    
    Matrix(int _n,int _m){
        n=_n,m=_m;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                mp[i][j]=0;
    }
    
    Matrix operator+(const Matrix &b)const{
        Matrix tmp(n,m);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                tmp.mp[i][j]=mp[i][j]+b.mp[i][j];
                tmp.mp[i][j]%=mod;
            }
        return tmp;
    }
    
    Matrix operator*(const Matrix &b)const{
        Matrix ret(n,b.m);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                for(int k=0;k<m;k++){
                    ret.mp[i][j]+=mp[i][k]*b.mp[k][j];
                    ret.mp[i][j]%=mod;
                }
        return ret;
    }
    
    Matrix operator^(long long k)const{
        Matrix ret(n,m),b(n,m);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                b.mp[i][j]=mp[i][j];
            ret.mp[i][i]=1;
        }
        while(k){
            if(k&1)
                ret=ret*b;
            b=b*b;
            k>>=1;
        }
        return ret;
    }
};

int t;
int a,b,c,d,p,n;

int main(){
    int i;
    
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&p,&n);
        if(n==1) printf("%d\n",a);
        else if(n==2) printf("%d\n",b);
        else{
            Matrix mc(3,1);
            mc.mp[0][0]=b;
            mc.mp[1][0]=a;
            mc.mp[2][0]=1;
            int now=3;
            Matrix mb(3,3);
            mb.mp[0][0]=d,mb.mp[0][1]=c,mb.mp[1][0]=1,mb.mp[2][2]=1;
            while(now<=n){
                int tmp=p/now;
                mb.mp[0][2]=tmp;
                if(tmp==0){
                    mc=(mb^(n-now+1))*mc;
                    break;
                }
                int x=p/tmp;
                if(x>n) x=n;
                mc=(mb^(x-now+1))*mc;
                now=x+1;
            } 
            printf("%lld\n",mc.mp[0][0]);
        }
    }
    
    return 0;
} 
View Code

1011:

 瞎贪就行,按每个关键字开优先队列,直到从最后一个队列弹出表示可以击杀,同时加上exp就好。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
#include <iostream>
#include <stack>
#include <set>
#include <map>
using namespace std;

struct FastIO
{
    static const int S = 200;
    int wpos;
    char wbuf[S];
    FastIO() :wpos(0) {}
    inline int xchar()
    {
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len) pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len) exit(0);
        return buf[pos++];
    }
    inline int read()
    {
        int s = 1, c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        if (c == '-') s = -1, c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x * s;
    }
    ~FastIO()
    {
        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
}io;

const int MAX=1e5+5; 

int t,n,k,ans;
struct node{
    int x[10],y[10];
}mon[MAX];
int v[10];

struct cmpa{
    bool operator()(node a,node b){
        return a.x[0]>b.x[0];
    }
};
struct cmpb{
    bool operator()(node a,node b){
        return a.x[1]>b.x[1];
    }
};
struct cmpc{
    bool operator()(node a,node b){
        return a.x[2]>b.x[2];
    }
};
struct cmpd{
    bool operator()(node a,node b){
        return a.x[3]>b.x[3];
    }
};
struct cmpe{
    bool operator()(node a,node b){
        return a.x[4]>b.x[4];
    }
};

priority_queue<node,vector<node>,cmpa> a;
priority_queue<node,vector<node>,cmpb> b;
priority_queue<node,vector<node>,cmpc> c;
priority_queue<node,vector<node>,cmpd> d;
priority_queue<node,vector<node>,cmpe> e;

int main(){
    int i,j;
    
    //freopen("1.in","r",stdin);
    //freopen("10.out","w",stdout);
    t=io.read();
    while(t--){
        ans=0;
        while(!a.empty()) a.pop();
        while(!b.empty()) b.pop();
        while(!c.empty()) c.pop();
        while(!d.empty()) d.pop();
        while(!e.empty()) e.pop();
        n=io.read(),k=io.read();
        for(i=0;i<k;i++) v[i]=io.read();
        for(i=0;i<n;i++){
            for(j=0;j<k;j++) mon[i].x[j]=io.read();
            for(j=0;j<k;j++) mon[i].y[j]=io.read();
            a.push(mon[i]);
        }
        if(k==1){
            while(!a.empty()){
                node now=a.top();
                if(v[0]>=now.x[0]){
                    ans++;
                    a.pop();
                    v[0]+=now.y[0];
                }
                else break;
            }
        }
        else if(k==2){
            while(!a.empty()){
                node now=a.top();
                if(v[0]>=now.x[0]){
                    a.pop();
                    b.push(now);
                    while(!b.empty()){
                        node now=b.top();
                        if(v[1]>=now.x[1]){
                            ans++;
                            b.pop();
                            v[0]+=now.y[0];
                            v[1]+=now.y[1];
                        }
                        else break;
                    }
                }
                else break;
            }
        }
        else if(k==3){
            while(!a.empty()){
                node now=a.top();
                if(v[0]>=now.x[0]){
                    a.pop();
                    b.push(now);
                    while(!b.empty()){
                        node now=b.top();
                        if(v[1]>=now.x[1]){
                            b.pop();
                            c.push(now);
                            while(!c.empty()){
                                node now=c.top();
                                if(v[2]>=now.x[2]){
                                    ans++;
                                    c.pop();
                                    v[0]+=now.y[0];
                                    v[1]+=now.y[1];
                                    v[2]+=now.y[2];
                                }
                                else break;
                            }
                        }
                        else break;
                    }
                }
                else break;
            }
        }
        else if(k==4){
            while(!a.empty()){
                node now=a.top();
                if(v[0]>=now.x[0]){
                    a.pop();
                    b.push(now);
                    while(!b.empty()){
                        node now=b.top();
                        if(v[1]>=now.x[1]){
                            b.pop();
                            c.push(now);
                            while(!c.empty()){
                                node now=c.top();
                                if(v[2]>=now.x[2]){
                                    c.pop();
                                    d.push(now);
                                    while(!d.empty()){
                                        node now=d.top();
                                        if(v[3]>=now.x[3]){
                                            ans++;
                                            d.pop();
                                            v[0]+=now.y[0];
                                            v[1]+=now.y[1];
                                            v[2]+=now.y[2];
                                            v[3]+=now.y[3];
                                        }
                                        else break;
                                    }
                                }
                                else break;
                            }
                        }
                        else break;
                    }
                }
                else break;
            }
        }
        else if(k==5){
            while(!a.empty()){
                node now=a.top();
                if(v[0]>=now.x[0]){
                    a.pop();
                    b.push(now);
                    while(!b.empty()){
                        node now=b.top();
                        if(v[1]>=now.x[1]){
                            b.pop();
                            c.push(now);
                            while(!c.empty()){
                                node now=c.top();
                                if(v[2]>=now.x[2]){
                                    c.pop();
                                    d.push(now);
                                    while(!d.empty()){
                                        node now=d.top();
                                        if(v[3]>=now.x[3]){
                                            d.pop();
                                            e.push(now);
                                            while(!e.empty()){
                                                node now=e.top();
                                                if(v[4]>=now.x[4]){
                                                    ans++;
                                                    e.pop();
                                                    v[0]+=now.y[0];
                                                    v[1]+=now.y[1];
                                                    v[2]+=now.y[2];
                                                    v[3]+=now.y[3];
                                                    v[4]+=now.y[4];
                                                }
                                                else break;
                                            }
                                        }
                                        else break;
                                    }
                                }
                                else break;
                            }
                        }
                        else break;
                    }
                }
                else break;
            }
        }
        
        printf("%d\n",ans);
        for(i=0;i<k;i++) printf("%d%c",v[i],i==k-1?'\n':' ');
    }
    
    return 0;
} 
View Code

猜你喜欢

转载自www.cnblogs.com/Hetui/p/9477405.html