本原串(HDU 2197 快速幂)

本原串

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1091    Accepted Submission(s): 350

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

F[n]=2^n-F[k],k为n的约数。

此题用反面情况求解,长度为n的串有2^n中,减去非本原串,非本原串肯定是由长度为v字串不断重复u次得到的,那么v必然是n的约数。

感觉很长时间没做题了脑袋笨了不少,约数枚举法忘了。不然肯定超时

 1 #include <cstring>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <map>
 6 using namespace std;
 7 typedef long long LL;
 8 map<int,int> m;
 9 map<int,int>::iterator ite;
10 LL n,ans;
11 LL mod_pow(LL x,LL n,int mod)
12 {
13     LL res=1;
14     while(n)
15     {
16         if(n&1)
17             res=res*x%mod;
18         x=x*x%mod;
19         n>>=1;
20     }
21     return res;
22 }
23 int cal(LL n)
24 {
25     int i,j;
26     if(m[n]!=0)
27         return m[n];
28     m[n]=mod_pow(2,n,2008)-2;
29     for(i=2;i*i<=n;i++)
30     {
31         if(n%i==0)
32         {
33             m[n]=(m[n]-cal(i)+2008)%2008;
34             if(i*i!=n)
35                 m[n]=(m[n]-cal(n/i)+2008)%2008;
36
37         }
38     }
39     return m[n];
40 }
41 int main()
42 {
43     m[0]=0;
44     m[1]=2;
45     m[2]=2;
46     //freopen("in.txt","r",stdin);
47     while(scanf("%d",&n)!=EOF)
48     {
49         if(n<=2)
50             printf("%d\n",m[n]);
51         else
52         {
53             m[n]=cal(n);
54             printf("%d\n",m[n]);
55         }
56     }
57 }

时间: 2024-08-29 09:50:45

本原串(HDU 2197 快速幂)的相关文章

hdu 5187 快速幂快速乘法

http://acm.hdu.edu.cn/showproblem.php?pid=5187 Problem Description As one of the most powerful brushes, zhx is required to give his juniors n problems. zhx thinks the ith problem's difficulty is i. He wants to arrange these problems in a beautiful wa

hdu 5187 快速幂 + 快速加 值得学习

就是以那个ai为分水岭,左边和右边都分别是单调增或单调减如图         就这四种情况,其中头两种总共就是两个序列,也就是从头到尾递增和从头到尾递减.         后两种方式就是把序列中德数分为左右两派,分完以后左右两边各自内部的排法就已经确定了,至于ai早就确定了(不是全局最大就是全局最小),而除了ai的每一个数都有选择在左或是在右两种选择,所以是2^(n-1),总共就是2^n,而这里包括了前两种的方案,所以要-4,最终应有2^n-2种.         看数据范围就知道要用快速幂,不

hdu 5187 快速幂+快速乘法

简单找出规律,答案为(2^n-2 )%p(1特判) 然而  n,p的最大值为 1e18 因此显然要快速幂,而且由于1e18 的平方超long long 所以在乘的时候要用快速乘法,快速乘法的原理和快速幂一样,a^b是 b个a相乘 ,快速乘法是b个a相加 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; long

hdu 2035 快速幂

很显然是快速幂,数据太小了,int就足够. 1 #include <iostream> 2 using namespace std; 3 4 int pow_mod( int a, int n, int m ) 5 { 6 int ans = 1; 7 a = a % m; 8 while ( n ) 9 { 10 if ( n & 1 ) 11 { 12 ans = ans * a % m; 13 } 14 a = a * a % m; 15 n = n >> 1; 16

hdu 1061 快速幂

求n^n的个位 Sample Input 2 3 4 Sample Output 7 6 直接快速幂了,注意要用long long 1 #include<cstdio> 2 long long quick_mod(long long a,long long b,long long m) { 3 long long ans = 1; 4 while (b) { 5 if (b&1) { 6 ans = (ans * a) % m; 7 b--; 8 } 9 b/=2; 10 a = a

hdu 1852(快速幂模+有除法的时候取模的公式)

Beijing 2008 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total Submission(s): 741    Accepted Submission(s): 291 Problem Description As we all know, the next Olympic Games will be held in Beijing in 2008. So the

快速幂取模总结

大白书上说的是模运算..而且给出了递归版的代码..我觉得还是非递归的好..而且加上了位运算,速度更快.下面是快速幂取模模板. 模板: LL quickpow(LL n, LL m, int mod) { LL ans=1; while(m>0) { if(m&1) ans=ans*n%mod; m=m >> 1; n=n*n%mod; } return ans; } 练习题目: HDU 1061 hdu 2035 快速幂取模总结

hdu 2197 求长度为n的本原串 快速幂+map

Problem Description由0和1组成的串中,不能表示为由几个相同的较小的串连接成的串,称为本原串,有多少个长为n(n<=100000000)的本原串?答案mod2008.例如,100100不是本原串,因为他是由两个100组成,而1101是本原串. Input输入包括多个数据,每个数据一行,包括一个整数n,代表串的长度. Output对于每个测试数据,输出一行,代表有多少个符合要求本原串,答案mod2008. Sample Input1234 Sample Output22612 长

HDU - 2197 本原串

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