分析了一下,大概就是{i1,i2...im}是n的所有因数,可知非本源串的个数是2^n - sum{f[i1],f[i2]...f[im]}。其中f[i]代表长度为i的非本源串个数。
为避免重复计算,首先要进行打表。。。
#include<stdio.h>
#include<string.h>
int dp[2][10010];
int n;
int pow(int a,int b)
{
int r = 1;
while(b)
{
if(b&1) r = (r*a)%2008;
a = (a*a)%2008;
b >>= 1;
}
return r;
}
int fun(int x)
{
int i, sum = 2, flag ;
int xx ;
if (x == 1 || x == 2) return 2;
if(x <= 10000) flag = 0, xx = x;
else flag = 1, xx = n/x;
if(dp[flag][xx] != -1) return dp[flag][xx];
for(i = 2; i*i <= x; i++)
{
if(x % i == 0)
{
sum += fun(i);
if(i*i != x) sum += fun(x/i);
}
sum %= 2008;
}
return dp[flag][xx] = (pow(2,x)-sum+2008)%2008 ;
}
int main()
{
while(~scanf("%d",&n))
{
memset(dp,-1,sizeof(dp));
printf("%d\n", fun(n));
}
return 0;
}
本文详细分析了如何通过计算所有因数来确定非本源串的数量,通过打表和递归函数实现了算法,并在代码中使用了C语言进行具体实现。
3981

被折叠的 条评论
为什么被折叠?



