["扫地"杯III day2]染色问题
描述 Description
做了HEOI2012的赵州桥(bridge)之后,liouzhou_101就感到极其的不爽,首先那题题目叙述巨渣,然后做法极坑。
不过那题是一道和染色有关的问题,于是在此同时也启发liouzhou_101想到了这样一个简单的问题:
在一串未打结的项链上(意思就是说项链的左端和右端不相连),有N颗珠子,你有M种颜色,然后就问你有多少种方法将每一颗珠子都染上颜色,使得任意两颗相邻的珠子的颜色不同。
liouzhou_101这种傻×自然不会做了,于是来向你请教…
当然,由于liouzhou_101的脑子构造极其简单,你不要想太多,请不要考虑Polya之类的本质相同,否则的话仅凭liouzhou_101的理解能力是不能理解的
不过那题是一道和染色有关的问题,于是在此同时也启发liouzhou_101想到了这样一个简单的问题:
在一串未打结的项链上(意思就是说项链的左端和右端不相连),有N颗珠子,你有M种颜色,然后就问你有多少种方法将每一颗珠子都染上颜色,使得任意两颗相邻的珠子的颜色不同。
liouzhou_101这种傻×自然不会做了,于是来向你请教…
当然,由于liouzhou_101的脑子构造极其简单,你不要想太多,请不要考虑Polya之类的本质相同,否则的话仅凭liouzhou_101的理解能力是不能理解的
输入格式 InputFormat
输入只有一行,三个正整数N、M和P,之间以一个空格隔开。
输出格式 OutputFormat
输出只有一行,表示染色的方法总数模P。
数据范围和注释 Hint
一共有324种染色方法,对13取模后是12。
对于10%的数据,N=1,M<=10,P<=10;
对于20%的数据,N<=10,M<=10,P<=100;
对于50%的数据,N,M,P<=1,000,000,000;
对于100%的数据,1<=N,M,P<=1,000,000,000,000,000,000,且M>=2。
对于10%的数据,N=1,M<=10,P<=10;
对于20%的数据,N<=10,M<=10,P<=100;
对于50%的数据,N,M,P<=1,000,000,000;
对于100%的数据,1<=N,M,P<=1,000,000,000,000,000,000,且M>=2。
看了题解第二种巧妙的解法后,我竟然还是傻帽的二分求2^xmodP的值,傻傻……
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<fstream> 5 using namespace std; 6 //ifstream fin("cin.in"); 7 //ofstream fout("test.out"); 8 9 long long N,M,P; 10 11 long long s,t;int totx=1,toty=1;long long f[140]; 12 long long Yu(long long x,long long y){ 13 long long ans=0;s=x;totx=0; 14 while(s>0) 15 { 16 if(s&1) 17 { 18 t=y;toty=0; 19 while(t>0) 20 { 21 if(t&1) 22 {ans+=f[totx+toty];ans%=P;} 23 t>>=1;toty++; 24 } 25 } 26 s>>=1;totx++; 27 } 28 return ans; 29 } 30 31 long long FangM(long long n){ 32 if(n==0) return 1; 33 if(n==1) return M%P; 34 35 long long ans=FangM(n/2); 36 ans=Yu(ans,ans); 37 if(n&1) ans=Yu(ans,M); 38 return ans; 39 } 40 41 int main() 42 { 43 cin>>N>>M>>P; 44 N--;M--; 45 f[0]=1; 46 for(int i=1;i<140;++i) 47 f[i]=(2*f[i-1])%P; 48 long long ans=FangM(N); 49 ans=Yu(ans,M+1); 50 cout<<ans<<endl; 51 return 0; 52 53 }