zoukankan      html  css  js  c++  java
  • BZOJ 4330 JSOI2012 爱之项链

    Problem G: JSOI2012 爱之项链

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 13  Solved: 5
    [Submit][Status][Discuss]

    Description

    在进香河,流传着这样一段美丽的故事。zyg与kzn是两个生活在进香河的孩子,一天,他们两人闹矛盾了,于是zyg送给了kzn一条精美的爱之项链。从此他们幸福生活在一起。 
    这则故事的真实性到今天已经没有意义了,然而我们关注的是那一条精美的爱之项链。这是一条由N个精致的戒指与一块特殊纪念品相连而成的环形,如下图中的爱心符号正是一种特殊纪念品。(据说是2012年情人节时zyg特意托人订制的)上面的每一枚戒指又是由M个带磁性的特殊彩色球状物组成的环形。也许你会认为,这所谓的戒指,更像是一条条小项链。 
    下图给出了一种可行的方案,其中左边描述的是单一的一枚戒指,右图描述的是项链。 
     
     
     
    这里,所有带磁性的特殊彩色球状物的颜色只有R种,这里我们用1到R来表示。如果一枚戒指可以通过顺时针或逆时针的旋转后与另外一枚戒指相同,则认为这是两枚相同的戒指。 
    对于一条爱之项链,要求满足任何相邻两枚戒指必须是不相同的。同时,特殊纪念品左右两枚戒指也必须是不同的。 
    现在给定N,M和R,问究竟有多少种不同的爱之项链。 
    注意: 
    1、特殊纪念品的插入位置不同,也许会得到不同的爱之项链。 
    2、这里我们只考虑旋转后是否相同,不考虑翻转操作,这一点不论是对于每一枚戒指,还是对于整条项链,都是这样的。 
     

    Input

    一行,三个正整数,分别是N,M和R。 
     

    Output

    一行,表示有多少种不同的爱之项链。你只需要将答案模3214567。 
     

    Sample Input

    10 5 4

    Sample Output

    1398595

    HINT

    对于100%的数据,N<=10^15,M<=10^9,R<=10^6。 


    题解:先用polya求出戒指种类m,于是问题转化为给你一个大小为n的环和m种颜色,求染色方案使得相邻颜色两两不同!
       •设一个F[n]表示为大小为n的环的方案数
       •求F[n]有两种方式
       •设g[i][0]表示长度为i的开头和末尾相同的序列的个数,g[i][1]表示表示长度为i的开头和末尾不相同的序列的个数。 
         那么最后的答案f(n)=g[n][1]。f表示的是一个和的形式,但是在求g[n][1]的过程中就已经统计过了长度是n的约数的序列的个数了。 
         比如在统计长度为6的时候,就会把123123这种序列统计进去了。素以这样求是正确的。 
             g[i][0]=g[i1][1] 
         g[i][1]=(o2)g[i][1]+(o1)g[i1][0] 
               =(o2)g[i][1]+(o1)g[i2][1] 
         所f(n)=(o2)f(n1)+(o1)f(n2) 
         这个东西可以矩乘,也可以用特征根求通项。 
         r2=(o2)r+(o1) 
         解r1=1,r2=d1 
         然后f(n)=c1r1n+c2r2n 
         可以把f(1)=0,f(2)=d(d1)带入就可以求出c1,c2 
         解c1=d1,c2=1 
         f(n)=(d1)(1)n+(d1)n
       •于是问题解决,此问题升级版请看:[Sdoi2013]项链

     

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #define base 3214567
    #define ll long long 
    using namespace std;
    ll n,m,r,ans;
    ll read()
    {
        ll x=0,f=1; char ch;
        while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') f=-1;
        while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
        return x*f;
    }
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a; 
    }
    ll ksm(ll x,ll k){
        ll res=1; for (ll i=k; i; i>>=1,x=1ll*x*x%base) if (i&1) res=1ll*res*x%base; return res;
    }
    ll phi(ll x)
    {
        ll res=x;
        for (int i=2; i<=sqrt(x); i++)
        {
            if (x%i==0) {while (x%i==0) x/=i; res=res*(i-1)/i;}
        }
        if (x!=1) res=res*(x-1)/x;
        return res;
    }
    ll get(ll N,ll M)
    {
        ll ans=0;
        //for (int i=1; i<=N; i++) ans=(ans+ksm(M,gcd(N,i)))%base;
        for (ll i=1; i*i<=N; i++) if (N%i==0) ans=((ans+phi(N/i)*ksm(M,i))%base+((i*i!=N)?phi(i)*ksm(M,N/i):0))%base;
        return ans;
    }
    ll get2(ll N,ll M)
    {
        //cout<<" "<<N<<" "<<M<<endl;
        ll ans=0;
        //ans=ksm(M,N+(gcd(N,i)%2)?1-M:M-1)); 
        ans=(ksm(M-1,N)+(N%2==0?M-1:1-M))%base;
        return ans;
    }
    int main()
    {
        n=read(); m=read(); r=read();
        m=get(m,r)*ksm(m,base-2)%base;
    //  cout<<m<<endl;
        ans=get2(n,m);
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    swift2.2当中的inout参数的使用
    Swift的7大误区
    Swift 设计指南之 编程规范
    我为什么用 SQLite 和 FMDB 而不用 Core Data
    ios学习笔记——代理设计模式
    ios学习笔记——UIImagePickerController
    ios学习笔记——保存图片到相册
    KVC中setValuesForKeysWithDictionary: (转载)
    ios学习笔记——GCD简介
    ios学习笔记——操作队列NSOperation的基本操作
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5952914.html
Copyright © 2011-2022 走看看