zoukankan      html  css  js  c++  java
  • [BZOJ]1064: [Noi2008]假面舞会

    题目大意:n个人,k种假面,每人戴一种,戴第i种的可以看见第i+1种,戴第k种的可以看见第1种,给出m条关系表示一个人可以看到另一个人,问k可能的最大值和最小值。(n<=100,000,m<=1,000,000)

    思路:染色,若点i颜色为ci,就把点i能到的点染成ci+1,能到点i的点染成ci-1,如果染之前已经染过了,设要染的点为j,则cj和ci+1(-1)模k同余,若cj不等于ci+1(-1),则k必然为|ci+1(-1)-cj|的因子,取gcd即可。若没有出现这种情况,最大答案为各连通块最长链的和。(稍微卡了个常卡到rank1 233)

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    char B[1<<21],*S=B,C;int X;
    inline int read()
    {
        while((C=*S++)<'0'||C>'9');
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X;
    }
    #define r register int
    #define MN 100000
    #define MM 1000000
    struct edge{int nx,t;}e[MM*2+5];
    int h[MN+5],rh[MN+5],en,c[MN+5],ans,mn,mx;
    inline void ins(int*h,int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
    inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
    inline int z(int x){return x<0?-x:x;}
    void dfs(int x)
    {
        for(r i=h[x];i;i=e[i].nx)
            c[e[i].t]?ans=gcd(ans,z(c[e[i].t]-c[x]-1)):
                (mx=max(mx,c[e[i].t]=c[x]+1),dfs(e[i].t),0);
        for(r i=rh[x];i;i=e[i].nx)
            c[e[i].t]?ans=gcd(ans,z(c[e[i].t]-c[x]+1)):
                (mn=min(mn,c[e[i].t]=c[x]-1),dfs(e[i].t),0);
    }
    int main()
    {
        fread(B,1,1<<21,stdin);
        int n,m,x,y,i,s=0;
        n=read();m=read();
        while(m--)x=read(),ins(h,x,y=read()),ins(rh,y,x);
        for(i=1;i<=n;++i)if(!c[i])c[i]=mn=mx=n,dfs(i),s+=mx-mn+1;
        if(ans)
        {
            if(ans<3)return 0*puts("-1 -1");
            for(i=3;i<=ans;++i)if(ans%i==0)break;
            return 0*printf("%d %d
    ",ans,i);
        }
        printf("%d %d
    ",s<3?-1:s,s<3?-1:3);
    }
  • 相关阅读:
    符合RESTful规范的API
    DRF 认证、权限、限制
    RESTful API终极版序列化封装
    RESTful API
    Django REST Framework
    前端之promise
    VueRouter
    Vue的生命周期
    三种常用的js数组去重方法
    dos命令查看端口状态
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ1064.html
Copyright © 2011-2022 走看看