hdu 2197 本原串(容斥定理)
阿新 • • 發佈:2019-01-22
本原串
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 547 Accepted Submission(s): 193
Problem Description 由0和1組成的串中,不能表示為由幾個相同的較小的串連線成的串,稱為本原串,有多少個長為n(n<=100000000)的本原串?
答案mod2008.
例如,100100不是本原串,因為他是由兩個100組成,而1101是本原串。
Input 輸入包括多個數據,每個資料一行,包括一個整數n,代表串的長度。
Output 對於每個測試資料,輸出一行,代表有多少個符合要求本原串,答案mod2008.
Sample Input 1 2 3 4
Sample Output 2 2 6 12
Author scnu
題解:假設f【i】代表本源串個數,則本源串f【n】= pow(2,n)-sigma(f【i】)-2,其中i | n 且 i>=2 ,
因為當 i 為 n 的約數時候,就可以重疊所有長度為 i 的本源串均可變成長度為 n 的非本源串,最後減去2是長度為1的時候重疊出的2種情況
#include<stdio.h> #include<map> #define mod 2008 using namespace std; map<int,int>mip; int fast_pow(int a,int b) { int res=1; while(b) { if(b&1) res=(res*a)%mod; a=(a*a)%mod; b>>=1; } return res; } int cal(int x) { int ans=(fast_pow(2,x)-2)%mod,i; if(mip[x]) return mip[x]; if(x==1) return mip[x]=2; for(i=2;i*i<=x;i++) { if(x%i!=0) continue; if(i*i==x) { ans=(ans-cal(i))%mod; } else { ans=(ans-cal(i))%mod; ans=(ans-cal(x/i))%mod; } } return mip[x]=(ans+mod)%mod; } int main() { int x; while(scanf("%d",&x)>0) { printf("%d\n",cal(x)); } }