zoukankan      html  css  js  c++  java
  • [20180613]校内模拟赛

    T1【Atcoder 2021】

      dp。f[i][j]表示前i个小朋友,分j个糖果所计算出来的value。前缀处理1~i的j次幂的和。

      f[0][0]=1

      f[i][j]=sigma(k=0~j)f[i-1][k]*qz[b[i]][j-k]-qz[a[i]-1][j-k]

      然后要注意取模操作。

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    #define mod 1000000007
    #define MN 405
    long long f[MN][MN],pw[MN][MN],qz[MN][MN];
    int n,c,a[MN],b[MN];
    void add(long long &x,long long y){x+=y;if(x>mod)x-=mod;}
    long long Abs(long long x){if(x<0) x+=mod;return x;}
    int main(){
        register int i,j,k;
        for(i=1;i<=400;i++) pw[i][0]=1;
        
        for(i=1;i<=400;i++)for(j=1;j<=400;j++) pw[i][j]=(pw[i][j-1]*i)%mod;
        for(i=1;i<=400;i++)for(j=0;j<=400;j++) qz[i][j]=(qz[i-1][j]+pw[i][j])%mod;
        
        n=read(),c=read();
        for(i=1;i<=n;i++) a[i]=read();
        for(i=1;i<=n;i++) b[i]=read();
        
        f[0][0]=1;
        
        for(i=1;i<=n;i++)for(j=0;j<=c;j++)for(k=j;k>=0;k--){
            add(f[i][j],f[i-1][k]*Abs(qz[b[i]][j-k]-qz[a[i]-1][j-k])%mod);
        }
        printf("%lld
    ",f[n][c]);
        return 0;
    }

    T2:【Atcoder 3911】

      首先,并查集各联通块中的最小点权和。

      显然,处理联通块的个数为(n-m),每连接一条边就要消耗掉2个点,所以如果(n-m-1)*2>n,就puts("Impossible").

      如果n-m=1,答案为0

      我们要选出(n-m-1)*2个点,其中,各联通块的最小点必须被取到,剩下取最小的(n-m-2)个点就行了。证明显然。

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    #define MN 100005
    int n,m,fa[MN],vis[MN],cnt,p[MN],ct;
    long long a[MN],ans;
    int findf(int x){return fa[x]==x?fa[x]:fa[x]=findf(fa[x]);}
    void union_(int x,int y){x=findf(x);y=findf(y);fa[x]=y;return;}
    vector<int> pic[MN];
    int main(){
        n=read(),m=read();
        register int i,j,x,y;
        for(i=1;i<=n;i++) a[i]=read(),fa[i]=i;
        for(i=1;i<=m;i++){
            x=read()+1,y=read()+1;
            union_(x,y);
        }
        if(m==n-1) return puts("0"),0;
        if((n-m-1)*2>n) return puts("Impossible
    "),0;
        for(i=1;i<=n;i++){
            if(vis[findf(i)]) pic[vis[fa[i]]].push_back(a[i]);
            else pic[vis[findf(i)]=++cnt].push_back(a[i]);
        }
        for(i=1;i<=cnt;i++){
            sort(pic[i].begin(),pic[i].end()),ans+=pic[i][0];
            for(j=1;j<pic[i].size();j++) p[++ct]=pic[i][j];
        }
        sort(p+1,p+ct+1);
        for(i=1;i<=n-m-2;i++) ans+=p[i];
        printf("%lld",ans);
        return 0;
    }

    T3:【Atcoder 3967】

      我们对4n^2个点进行两次染色处理。

      当D为奇数时,显然D只能被分成奇数和偶数的平方和,所以直接将图进行交叉染色,同色的显然距离不会为D。

      当D为偶数时,我们通过旋转图,是相邻点的边为原先的对角线,然后D>>=1,通过不断的旋转,直至D是一个奇数。

      经过不断的画图和总结,我们发现最终图的染色方法为(用01表示),记D中含有2的指数为k,记squ=2^(k>>1)

      如果k为偶数:

                 0 0 0 1 1 1 0 0 0 

         0 0 0 1 1 1 0 0 0 

         0 0 0 1 1 1 0 0 0 

         1 1 1 0 0 0 1 1 1

           1 1 1 0 0 0 1 1 1 

                1 1 1 0 0 0 1 1 1

                 0 0 0 1 1 1 0 0 0 

         0 0 0 1 1 1 0 0 0 

         0 0 0 1 1 1 0 0 0 

         其中,任意一个纯1或纯0的矩阵边长是squ。

      如果k为奇数:

        0 0 0 0 0 0 0 0 0 

        0 0 0 0 0 0 0 0 0 

        0 0 0 0 0 0 0 0 0

        1 1 1 1 1 1 1 1 1

        1 1 1 1 1 1 1 1 1

        1 1 1 1 1 1 1 1 1

        0 0 0 0 0 0 0 0 0 

        0 0 0 0 0 0 0 0 0 

        0 0 0 0 0 0 0 0 0

      其中,任意一个纯1或纯0的矩阵行数是squ。

      证明的话,多画画图就发现了。

      然后对于一个点,它会有4种染色情况(11,10,00,01),根据4种情况将图分成4个集合。

      根据平均数的性质,4n^2个点分为4个集合,必定有一个集合它的个数大于等于n^2.

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    #define MN 605
    pair<int,int> mp[MN<<1];
    int N,D1,D2,cc;
    bool col[MN][MN][2];
    struct node{int x,y;};
    vector<node> G[5];
    void solve(int D,int l){
        register int i,j,k,ct=0,squ=1;
        while(~D&1){ct++;D>>=1;}
        squ=1<<(ct>>1);
        if(~ct&1){
            for(i=0;i<N*2;i++)for(j=0;j<N*2;j++)col[i][j][l]=((i/squ)+(j/squ))&1;
        }
        else{
            for(i=0;i<N*2;i++)for(j=0;j<N*2;j++) col[i][j][l]=(i/squ)&1;
        }
    }
    int main(){
        register int i,j;
        N=read(),D1=read(),D2=read();
        solve(D1,0),solve(D2,1);
        for(i=0;i<N<<1;i++)for(j=0;j<N<<1;j++)
        G[col[i][j][0]+col[i][j][1]<<1].push_back((node){i,j});
        for(i=0;i<4;i++)if(G[i].size()>=N*N){
            for(j=0;j<N*N;j++) printf("%d %d
    ",G[i][j].x,G[i][j].y);
            return 0;
        }
        return 0;
    }

       来自PaperCloud的博客,未经允许,请勿转载,TKS!

  • 相关阅读:
    新浪微博评论抓取
    ubuntu下ssh登录特别慢的问题
    在ubuntu13.04上安装Mac主题
    ubuntu修复grub
    linux卸载自己编译安装的内核
    ubuntu下搭建sublime text2的java开发环境
    CentOS防火墙对特定端口允许
    python笔记:python的表达式
    python笔记一:python变量
    python笔记一:python初步
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/9183942.html
Copyright © 2011-2022 走看看