zoukankan      html  css  js  c++  java
  • 【BZOJ】【3004】吊灯

    思路题


      要将整棵树分成大小相等的连通块,那么首先我们可以肯定的是每块大小x一定是n的约数,且恰好分成$frac{n}{x}$块,所以我有了这样一个思路:向下深搜,如果一个节点的size=x,就把这个子树砍掉做成一个连通块,并更新父亲及祖先的size,这样递归地切,如果最后size[1]==0就表示所有的点都被切成了一个连通块……

      然后我只得了40分= =明显会T啊……

      事实上有一个更进一步的结论:上个做法中每次“砍”的点一定是size[i]%x==0的点!所以我们只需要判一下size[i]%x==0的点的数量是否等于$frac{n}{x}$即可……

      这个算法就可以顺利过掉所有数据了(复杂度O(NloglogN))

     1 /**************************************************************
     2     Problem: 3004
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:3888 ms
     7     Memory:20024 kb
     8 ****************************************************************/
     9  
    10 //Huce #3 C
    11 #include<cmath>
    12 #include<vector>
    13 #include<cstdio>
    14 #include<cstdlib>
    15 #include<cstring>
    16 #include<iostream>
    17 #include<algorithm>
    18 #define rep(i,n) for(int i=0;i<n;++i)
    19 #define F(i,j,n) for(int i=j;i<=n;++i)
    20 #define D(i,j,n) for(int i=j;i>=n;--i)
    21 using namespace std;
    22  
    23 int getint(){
    24     int v=0,sign=1; char ch=getchar();
    25     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
    26     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
    27     return v*sign;
    28 }
    29 typedef long long LL;
    30 const int N=1200010,INF=~0u>>2;
    31 /*******************tamplate********************/
    32 int Case=0,n,fa[N],sz[N],a[N],c[N];
    33 bool jud(int x){
    34     int cnt=0;
    35     for(int i=x;i<=n;i+=x) cnt+=c[i];
    36     return cnt==n/x;
    37 }
    38 void solve(){
    39     memset(sz,0,sizeof sz);
    40     memset(c,0,sizeof c);
    41     printf("Case #%d:
    ",++Case);
    42     D(i,n,1){
    43         sz[i]++;
    44         sz[fa[i]]+=sz[i];
    45         c[sz[i]]++;
    46     }
    47     F(i,1,n) if (n%i==0)
    48         if (jud(i)) printf("%d
    ",i);
    49 }
    50 void change(){
    51     F(i,2,n) fa[i]=(fa[i]+19940105)%(i-1)+1;
    52 }
    53 int main(){
    54 #ifndef ONLINE_JUDGE
    55     freopen("input.txt","r",stdin);
    56 //  freopen("output.txt","w",stdout);
    57 #endif
    58     n=getint(); fa[1]=0;
    59     F(i,2,n) scanf("%d%*c",&fa[i]);
    60     solve();
    61     F(i,1,9){
    62         change();
    63         solve();
    64     }
    65     return 0;
    66 }
    View Code

    3004: 吊灯

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 24  Solved: 17
    [Submit][Status][Discuss]

    Description

           Alice家里有一盏很大的吊灯。所谓吊灯,就是由很多个灯泡组成。只有一个灯泡是挂在天花板上的,剩下的灯泡都是挂在其他的灯泡上的。也就是说,整个吊 灯实际上类似于一棵树。其中编号为1的灯泡是挂在天花板上的,剩下的灯泡都是挂在编号小于自己的灯泡上的。
           现在,Alice想要办一场派对,她想改造一下这盏吊灯,将灯泡换成不同的颜色。她希望相同颜色的灯泡都是相连的,并且每一种颜色的灯泡个数都是相同的。
           Alice希望你能告诉她,总共有哪些方案呢?
           Alice是一个贪心的孩子,如果她发现方案不够多,或者太多了,就会很不高兴,于是她会尝试调整。对于编号为x(x≠1)的灯泡,如果原来是挂在编号为 f[x]的灯泡上,那么Alice会把第x个灯泡挂到第 ( f[x] + 19940105 ) mod (x-1) + 1 个灯泡上。
           由于九在古汉语中表示极大的数,于是,Alice决定只调整9次。对于原始状态和每一次调整过的状态,Alice希望你依次告诉她每种状态下有哪些方案。

    Input

           第一行一个整数n,表示灯泡的数量。
           接下来一行,有n-1个整数Ui,第i个数字表示第i+1个灯泡挂在了Ui个的下面。保证编号为1的灯泡是挂在天花板上的。数字之间用逗号‘,’隔开且最后一个数字后面没有逗号。

    Output

           对于10种状态下的方案,需要按照顺序依次输出。
    对于每一种状态,需要先输出单独的一行,表示状态编号,如样例所示。
    之后若干行,每行1个整数,表示划分方案中每种颜色的灯泡个数。
           按升序输出。
     

    Sample Input

    6
    1,2,3,4,5

    Sample Output

    1 Case #1: 1 2 3 6 Case #2: 1 2 6 Case #3: 1 3 6 Case #4: 1 3 6 Case #5: 1 3 6 Case #6: 1 2 6 Case #7: 1 2 3 6 Case #8: 1 6 Case #9: 1 2 6 Case #10: 1 3 6
    View Code

    HINT



           对于100%的数据,n<=1.2*106。

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    dblink && 视图 数据库二合一
    oracle mybatis 逆向工程 应当注意的问题
    关于使用vue搭建前后端分离的项目,部署过程遇到的问题
    详解vue静态资源打包中的坑与解决方案
    bootstarap table 分页导出 vue版
    react中两个控件不是父子关系该怎么传递消息或任意控件怎么传递消息
    虚拟DOM中key的作用
    修改Antd的List列表的单个数据行
    移动端开发如何关闭手机键盘
    在一行显示两个数据,左边的数据右对齐,右边的数据左对齐
  • 原文地址:https://www.cnblogs.com/Tunix/p/4438920.html
Copyright © 2011-2022 走看看