码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2197 推公式

时间:2015-05-02 15:12:06      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

题意:由0和1组成的串中,不能表示为由几个相同的较小的串连接成的串,称为本原串,有多少个长为n(n<=100000000)的本原串?
答案mod2008.例如,100100不是本原串,因为他是由两个100组成,而1101是本原串。

 

f[n]=2^n -  求和(f[i])  -2  其中i是n的大于等于2的约数。  那个-2是由0和1组成的串

 

一开始写数组,直接超了,没想到这里居然可以用map,新技能

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 2008
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 #define cl(a) memset(a,0,sizeof(a))
13 #define ts printf("*****\n");
14 const int MAXN=100000005;
15 int n,m,tt;
16 //int f[MAXN];  这样就会超内存
17 map<int,int> f;
18 int pow_m(int a,int n)
19 {
20     int ret=1;
21     int tmp=a%MOD;
22     while(n)
23     {
24         if(n&1)
25         {
26             ret*=tmp;
27             ret%=MOD;
28         }
29         tmp*=tmp;
30         tmp%=MOD;
31         n>>=1;
32     }
33     return ret;
34 }
35 int fun(int x)
36 {
37     if(f[x]!=0) return f[x];
38     if(x==1)    return f[x]=2;
39     int sum=pow_m(2,x);
40     sum%=MOD;
41     sum-=2;
42     for(int i=2;i*i<=x;i++)
43     {
44         if(x%i==0)
45         {
46             if(i*i==x)
47             {
48                 sum-=fun(i);
49                 sum=(sum+MOD)%MOD;
50             }
51             else
52             {
53                 sum-=fun(i);
54                 sum-=fun(x/i);
55                 sum=(sum+MOD)%MOD;
56             }
57         }
58     }
59     return f[x]=(sum+MOD)%MOD;
60 }
61 int main()
62 {
63     int i,j,k;
64     #ifndef ONLINE_JUDGE
65     freopen("1.in","r",stdin);
66     #endif
67     f.clear();
68     while(scanf("%d",&n)!=EOF)
69     {
70         printf("%d\n",fun(n));
71     }
72 }

 

hdu 2197 推公式

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4471967.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!