zoukankan      html  css  js  c++  java
  • SPOJ 422 Transposing is Even More Fun(polay计数)

    题目链接:http://www.spoj.com/problems/TRANSP2/

    题意:

    思路:不妨设a=1,b=2,

    我们发现(001,010,100)组成一个置换,(011,110,101)组成一个置换。那么对于同一个置换中元素,设置换大小为x,则需要x-1次交换。因此,我们若找到循环节的个数K,那么答案即为2^(a+b)-K.

    a+b个珠子的项链,每个珠子可以用两种颜色涂色,通过每次左移a个珠子得到的相同的视为相同。求不同项链的个数。问题就转化成这个。设g=Gcd(a,a+b),则置换群个数为G=(a+b)/g。其实可以看做有G个珠子,每个珠子可以用2^g种颜色涂色。答案为:

     

    int a,b,Pow[N],phi[N];
    int prime[1005],tag[1005],cnt;
    
    
    void init()
    {
        Pow[0]=1;
        int i,j;
        for(i=1;i<N;i++) Pow[i]=Pow[i-1]*2%mod;
    
        phi[1]=1;
        for(i=2;i<N;i++) if(!phi[i]) for(j=i;j<N;j+=i)
        {
            if(!phi[j]) phi[j]=j;
            phi[j]=phi[j]/i*(i-1);
        }
    
        for(i=1;i<N;i++) phi[i]%=mod;
    
        for(i=2;i<=1000;i++) if(!tag[i])
        {
            prime[cnt++]=i;
            for(j=i+i;j<=1000;j+=i) tag[j]=1;
        }
    }
    
    int Gcd(int x,int y)
    {
        if(y==0) return x;
        return Gcd(y,x%y);
    }
    
    
    i64 exGcd(int a,int b,i64 &x,i64 &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        i64 temp=exGcd(b,a%b,x,y);
        i64 t=x;
        x=y;
        y=t-a/b*y;
        return temp;
    }
    
    int p[105],q[105],num;
    
    void split(int n)
    {
        num=0;
        int i;
        for(i=0;i<cnt&&prime[i]*prime[i]<=n;i++) if(n%prime[i]==0)
        {
            p[num]=prime[i];
            q[num]=0;
            while(n%prime[i]==0)
            {
                q[num]++;
                n/=prime[i];
            }
            num++;
        }
        if(n>1) p[num]=n,q[num++]=1;
    }
    
    
    int ans,m,L;
    
    int calPow(int a,int b)
    {
        int ans=1;
        while(b)
        {
            if(b&1) ans=(i64)ans*a%mod;
            a=(i64)a*a%mod;
            b>>=1;
        }
        return ans;
    }
    
    void cal(int t)
    {
        int x=L/t;
        ans+=(i64)calPow(m,t)*phi[x]%mod;
        ans%=mod;
    }
    
    void DFS(int dep,int t)
    {
        if(dep==num)
        {
            cal(t);
            return;
        }
        int i;
        for(i=0;i<=q[dep];i++)
        {
            DFS(dep+1,t);
            t*=p[dep];
        }
    }
    
    int main()
    {
        init();
        rush()
        {
            RD(a,b);
            if(!a||!b)
            {
                puts("0");
                continue;
            }
            b+=a;
            int k=Gcd(a,b);
            L=b/k;
            split(L); ans=0; m=Pow[k];
            DFS(0,1);
            i64 x,y;
            exGcd(L,mod,x,y);
            x=(x%mod+mod)%mod;
            ans=ans*x%mod;
            ans=Pow[b]-ans;
            ans=(ans%mod+mod)%mod;
            PR(ans);
        }
    }
    

      

     

  • 相关阅读:
    计算机病毒
    wordpress搬家教程
    javascript的DOM学习之选项卡制作
    javascript的DOM学习上
    [转]jQuery 引用地址{包括jquery和google提供的地址}, 节省你不必要的流量
    CSS3属性之:transition
    CSS3属性之:animastion
    css3学习系列之box-shadow(1)
    使ie678支持css3伪类选择器的插件
    个人网站名称填写注意事项
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/3457446.html
Copyright © 2011-2022 走看看