zoukankan      html  css  js  c++  java
  • NOI 2008 假面舞会

    题目描述

    一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。

    今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具的人。

    为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k 类面具的人能看到戴第1 类面具的人的编号。

    参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己算出有多少类面具,于是他开始在人群中收集信息。

    栋栋收集的信息都是戴第几号面具的人看到了第几号面具的编号。如戴第2号面具的人看到了第5 号面具的编号。栋栋自己也会看到一些编号,他也会根据自己的面具编号把信息补充进去。

    由于并不是每个人都能记住自己所看到的全部编号,因此,栋栋收集的信 息不能保证其完整性。现在请你计算,按照栋栋目前得到的信息,至多和至少有多少类面具。由于主办方已经声明了k≥3,所以你必须将这条信息也考虑进去。

    SOL:我们可以发现,这应该是一张图,而答案应该是这张图中所有环的gcd。这是显然的。(我们可以考虑一个环,环走n边也是一个环,所以是gcd)。所以我们考虑如何找环:用并查集(维护路径长度)维护环的长度。就是把每次读进来一条边,就判是否在一个集合里,不是就并起来,不然就找到一个环,把所有环gcd就是答案。

    #include<bits/stdc++.h>
    #define N 100011
    #define MARICLE __attribute__((optimize("-O2")))
    #define getchar nc
    using namespace std;
    int b,n,m,f[N],nf[N],aa,bb,sum,sums,i,a,bbb,anfa,anfb,ans,tmax[N],tmin[N],len,us[N],usmax;
    char c;
    inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    MARICLE inline void read (int &x){
        c=getchar();
        for (;!('0'<=c && c<='9');c=getchar());
        for (x=0;('0'<=c && c<='9');) {
            x=x*10+c-'0';c=getchar();} 
    }
    MARICLE int gcd (int a,int b){
        if (b==0) return a;
        return gcd(b,a%b);
    }
    MARICLE int Find(int x)
    {
        int top,j,next;
        top=x;
        while (top!=f[top]) top=f[top];
        while (top!=x) 
        {
            next=f[x]; f[x]=top;
            j=next;
            do
            {
                nf[x]+=nf[j];
                j=f[j];
            }while (f[j]!=j);
            x=next;
        }
        return top;
    }
    MARICLE int gg() {
        int ggg=sqrt(ans),llll=0;
        for (i=3;i<=ggg;i++)
         if (ans%i==0) {
             llll=i;break;
         }
        if (ans%2==0&&llll==0) llll=ans/2;
        if (llll==0)
         printf("%d %d
    ",ans,ans);
        else printf("%d %d
    ",ans,llll);
    }
    MARICLE int main () {
        freopen("party2008.in","r",stdin);
        freopen("party2008.out","w",stdout);
        read(n); read(m);
        for (i=n;i;i--) f[i]=i;
        for (i=1;i<=m;i++)
          {
           read(a); read(bbb);
              anfa=Find(a); anfb=Find(bbb);
            if (anfa==anfb) {
                if (nf[a]-nf[bbb]!=-1)  {
                    if (ans==0) ans=nf[a]-nf[bbb]+1;
                    else  ans=gcd(ans,nf[a]-nf[bbb]+1);
                }
            }
            if (anfa!=anfb) {
                  f[anfb]=anfa; nf[anfb]=nf[a]-nf[bbb]+1;
              }
          }
          if (ans) {
              if (ans<=2) { printf("-1 -1
    ");return 0;}
            else  gg();
          }
          if (!ans) {
              for (i=n;i  ;i--) Find(i);
              for (i=1;i<=n;i++)
               {
                   tmin[f[i]]=min(tmin[f[i]],nf[i]);
                   tmax[f[i]]=max(tmax[f[i]],nf[i]);
                   us[f[i]]=1;
               }
            for (i=1;i<=n;i++)
             if (us[i]==1){
                 len=max(len,tmax[i]-tmin[i]+1);
                 usmax+=tmax[i]-tmin[i]+1;
              } 
              len=max(len,3);
              if (usmax<3) {printf("-1 -1
    ");return 0;}
              if (len<=usmax) printf("%d %d
    ",usmax,3);
          }
    }
  • 相关阅读:
    js中 var let const 区别
    img标签src引用网络图片,响应403的解决方法
    统计开发push数据
    gp日志查看
    node之path模块
    算法相关问题
    常用的 curl 发送 http 请求 命令
    Python与Go列表切片越界的对比
    golang时间与时区相关操作总结
    go语言结构体转map的方法
  • 原文地址:https://www.cnblogs.com/rrsb/p/7944335.html
Copyright © 2011-2022 走看看