• 【POJ 2154】 Color (置换、burnside引理)


    Color

    Description

    Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). Your job is to calculate how many different kinds of the necklace can be produced. You should know that the necklace might not use up all the N colors, and the repetitions that are produced by rotation around the center of the circular necklace are all neglected. 

    You only need to output the answer module a given number P. 

    Input

    The first line of the input is an integer X (X <= 3500) representing the number of test cases. The following X lines each contains two numbers N and P (1 <= N <= 1000000000, 1 <= P <= 30000), representing a test case.

    Output

    For each test case, output one line containing the answer.

    Sample Input

    5
    1 30000
    2 30000
    3 30000
    4 30000
    5 30000
    

    Sample Output

    1
    3
    11
    70
    629
    

    Source

     

     

    【分析】  

      经典的置换和burnside引理应用。只有旋转。

      考虑旋转i个单位,那么循环节有gcd(n,i)个

      可以化出求 sigma(n^gcd(i,n))/n

      根据莫比乌斯反演得 sigma(n^d*phi[n/d])/n   (d|n) 【表示我莫比乌斯反演白学了ORZ

      即sigma(n^(d-1)*phi[n/d]) (d|n)

      就算一算就好了。【不用欧拉筛,筛不到n的,先求出n的质因子,那么d的质因子也在里面,然后根据定义分解质因数求phi

      最后要除以n,不能求逆元哦,每次少乘一个n就好了。

     

      然而我还WA着!!!!【AC了再放代码吧

      好了AC了:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 35000
     8 
     9 int n,p;
    10 int pri[Maxn],phi[Maxn],pl;
    11 int d[Maxn],dl;
    12 bool vis[Maxn];
    13 
    14 void init()
    15 {
    16     pl=0;
    17     memset(vis,0,sizeof(vis));
    18     for(int i=2;i<=Maxn-110;i++)
    19     {
    20         if(vis[i]==0)
    21         {
    22             pri[++pl]=i;
    23             phi[i]=i-1;
    24         }
    25         for(int j=1;j<=pl;j++)
    26         {
    27             if(i*pri[j]>Maxn-110) break;
    28             vis[i*pri[j]]=1;
    29             if(i%pri[j]!=0) phi[i*pri[j]]=phi[i]*(pri[j]-1);
    30             else phi[i*pri[j]]=phi[i]*pri[j];
    31             if(i%pri[j]==0) break;
    32         }
    33     }
    34     phi[1]=1;
    35     // for(int i=2;i<=10;i++) printf("%d ",phi[i]);
    36     // printf("
    ");
    37 }
    38 
    39 int qpow(int a,int b,int p)
    40 {
    41     a%=p;
    42     int ans=1;
    43     while(b)
    44     {
    45         if(b&1) ans=(ans*a)%p;
    46         a=(a*a)%p;
    47         b>>=1;
    48     }
    49     return ans;
    50 }
    51 
    52 void get_d(int n)
    53 {
    54     dl=0;
    55     for(int i=1;i<=pl;i++) if(n%pri[i]==0)
    56     {
    57         while(n%pri[i]==0) n/=pri[i];
    58         d[++dl]=pri[i];
    59     }
    60     if(n!=1) d[++dl]=n;
    61 }
    62 
    63 int gphi(int x)
    64 {
    65     int ans=x;
    66     for(int i=1;i<=dl;i++) if(x%d[i]==0)
    67     {
    68         ans=ans/d[i]*(d[i]-1);
    69     }
    70     return ans;
    71 }
    72 
    73 int main()
    74 {
    75     int T;
    76     scanf("%d",&T);
    77     init();
    78     while(T--)
    79     {
    80         scanf("%d%d",&n,&p);
    81         get_d(n);
    82         int ans=0;
    83         for(int i=1;i*i<=n;i++) if(n%i==0)
    84         {
    85             ans=(ans+(qpow(n,i-1,p)*(gphi(n/i)%p)))%p;
    86             if(i*i!=n) ans=(ans+(qpow(n,n/i-1,p)*(phi[i]%p)))%p;
    87         }
    88         printf("%d
    ",ans);
    89     }
    90     return 0;
    91 }
    View Code

     

    2017-01-13 11:48:09

  • 相关阅读:
    Xah Lee Web 李杀网
    About Unixstickers
    Amazon.com: NEW VI AND VIM EDITOR KEYBOARD STICKER: Office Products
    Company Story | Vistaprint
    8月30号周五香港接单ING~~化妆品只加10元!!!!!!
    贝佳斯绿泥多久用一次?_百度知道
    贝佳斯绿泥_百度百科
    [PHP]利用MetaWeblog API实现XMLRPC功能
    The tempfile module
    20.23. xmlrpclib — XML-RPC client access — Python v2.7.5 documentation
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6282168.html
Copyright © 2020-2023  润新知