zoukankan      html  css  js  c++  java
  • 解题:SPOJ 422 Transposing is Even More Fun

    题面

    这种换来换去的东西很容易想到置换群那一套,然后题目甚至还暗示了二进制=。=

    直接换的话显然是$2^{a+b}$次,但是一个循环节里可以少换一次,然后问题就变成了数循环节

    在一个循环节里的位置有什么特征?用二进制表示位置,那么他们的位置可以通过循环左移a位/循环右移b位互相表示,然后问题就变成了:在左移a位/右移b位的置换群作用下,在a+b个01构成的环里找等价类。仍然不好做,因为现在直接Burnside做不出来,Polya又还没法做,继续转换

    我们把每$gcd(a,b)$个数缩成一个,也就是转成$frac{(a+b)}{gcd(a,b)}$个环数等价类。这样的好处是旋转都变成了1位,然后套上Polya就可以了,大概需要卡一卡常?

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=1e6+60,mod=1e6+3;
     6 int T,a,b,cnt,c1,c2,pwe[10],prf[10];
     7 int pw[N],npr[N],pri[N],mind[N],fac[N],fai[N];
     8 int GCD(int a,int b)
     9 {
    10     return b?GCD(b,a%b):a;
    11 }
    12 void Add(int &x,int y)
    13 {
    14     x+=y;
    15     if(x>=mod) x-=mod;
    16 }
    17 int Qpow(int x,int k)
    18 {
    19     if(k==1) return x;
    20     int tmp=Qpow(x,k/2);
    21     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
    22 }
    23 void Pre()
    24 {
    25     npr[1]=true,mind[1]=1;
    26     for(int i=2;i<=1000000;i++)
    27     {
    28         if(!npr[i]) pri[++cnt]=i,mind[i]=i;
    29         for(int j=1,k;j<=cnt&&(k=i*pri[j])<=1000000;j++)
    30         {
    31             npr[k]=true,mind[k]=pri[j];
    32             if(i%pri[j]==0) break;
    33         }
    34     }
    35     pw[0]=1;
    36     for(int i=1;i<=1000000;i++)
    37         pw[i]=pw[i-1]*2%mod;
    38 }
    39 void DFS(int idx,int num,int phi)
    40 {
    41     if(idx>c2)
    42         fac[++c1]=num,fai[num]=phi;
    43     else
    44     {
    45         int pr=prf[idx];
    46         DFS(idx+1,num,phi);
    47         DFS(idx+1,num*=pr,phi*=pr-1);
    48         for(int i=2;i<=pwe[idx];i++)
    49             DFS(idx+1,num*=pr,phi*=pr);
    50     }
    51 }
    52 void Decompose(int x)
    53 {
    54     if(x==1)
    55         fac[c1=1]=1;
    56     else
    57     {
    58         c2=0;
    59         while(x!=1)
    60         {
    61             prf[++c2]=mind[x],pwe[c2]=0;
    62             while(x%prf[c2]==0) x/=prf[c2],pwe[c2]++;
    63         }
    64         c1=0,DFS(1,1,1);
    65     }
    66 }
    67 int Query(int len,int col)
    68 {
    69     int ret=0;
    70     Decompose(len);
    71     for(int i=1;i<=c1;i++)
    72         Add(ret,1ll*fai[len/fac[i]]*Qpow(col,fac[i])%mod);
    73     return 1ll*ret*Qpow(len,mod-2)%mod;
    74 }
    75 int main()
    76 {
    77     Pre();
    78     scanf("%d",&T);
    79     while(T--)
    80     {
    81         scanf("%d%d",&a,&b);
    82         if(!a||!b) puts("0");
    83         else
    84         {
    85             int g=GCD(a,b);
    86             printf("%d
    ",(pw[a+b]-Query((a+b)/g,pw[g])+mod)%mod);
    87         }
    88     }
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    sqlhelper使用指南
    大三学长带我学习JAVA。作业1. 第1讲.Java.SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行 大三学长带我学习JAVA。作业1.
    pku1201 Intervals
    hdu 1364 king
    pku 3268 Silver Cow Party
    pku 3169 Layout
    hdu 2680 Choose the best route
    hdu 2983
    pku 1716 Integer Intervals
    pku 2387 Til the Cows Come Home
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10433597.html
Copyright © 2011-2022 走看看