题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2197
题目大意:
本原串是不能表示为由几个较小的串连接而成的串,问有多少个长度为n的本原串
思路分析:
长度为n的01串的总数为2^n,那么总数减掉非本原串就是本原串,非本原串可以看成由几个相同的本原串连接而成,即2^n减掉所有长度为小于n且能被n整除的本原串即可(一个递推的过程,f[n] = 2^n - 求和f[i],其中i能被n整除 )。
题目代码:
#include<iostream>
#include<cstdio>
using namespace std;
const int mod = 2008;
int pow(int a, int b)
{
int temp = a;
int ans = 1;
while(b)
{
if(b&1)
{
ans *= temp;
ans %= mod;
}
temp *= temp;
temp %= mod;
b >>= 1;
}
// cout<<ans<<endl;
return ans;
}
int solve(int n)
{
int ans;
ans = pow(2, n);
ans %= mod;
if(n == 1)
return ans;
ans -= 2;
// cout<<ans<<endl;
for(int i = 2; i*i <= n; i++)
{
if(n % i == 0)
{
if(i*i == n)
{
ans -= solve(i);
ans %= mod;
}
else
{
ans -= solve(i);
ans -= solve(n/i);
ans %= mod;
}
}
// cout<<i<<endl;
}
// cout<<n<<endl;
return (ans + mod)%mod;
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
cout<<solve(n)<<endl;
}
return 0;
}