首页 > 代码库 > HDU - 2197 本原串
HDU - 2197 本原串
Description
由0和1组成的串中,不能表示为由几个相同的较小的串连接成的串,称为本原串,有多少个长为n(n<=100000000)的本原串?
答案mod2008.
例如,100100不是本原串,因为他是由两个100组成,而1101是本原串。
答案mod2008.
例如,100100不是本原串,因为他是由两个100组成,而1101是本原串。
Input
输入包括多个数据,每个数据一行,包括一个整数n,代表串的长度。
Output
对于每个测试数据,输出一行,代表有多少个符合要求本原串,答案mod2008.
Sample Input
1 2 3 4
Sample Output
2 2 6 12
思路:从总的串里减去非本原串,非本原串可以有本原串组成,只有长度是n的约数就行了,当然还有考虑全0和全1的情况
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> typedef long long ll; using namespace std; const int mod = 2008; map<int, int > mp; int pow_mod(int a, int n) { int ans = 1; int tmp = a; while (n) { if (n & 1) ans = ans * tmp % mod; tmp = tmp * tmp % mod; n >>= 1; } return ans; } int cal(int x) { if (mp[x] != 0) return mp[x]; if (x == 1) return mp[x] = 2; int ans = pow_mod(2, x); ans = (ans - 2 + mod) % mod; for (int i = 2; i*i <= x; i++) { if (x % i != 0) continue; if (i * i == x) { ans -= cal(i); continue; } else { ans = (ans - cal(i) + mod) % mod; ans = (ans - cal(x/i) + mod) % mod; } } return mp[x] = (ans + mod) % mod; } int main() { int n; while (scanf("%d", &n) != EOF) { printf("%d\n", cal(n)); } return 0; }
HDU - 2197 本原串
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。