51Nod-1675-序列变换
2017-03-07 20:56
387 查看
ACM模版
这里有两个代码,一个是我的智商所能达到的暴力解题思路(代码 One),另一个则是利用莫比乌斯反演得到的超牛逼的解法儿(代码 Two),数学家的世界我不懂~~~
这辈子,我最讨厌的人就是数学家、物理学家、化学家,给我的学生时代造成了多么大的心理阴影啊!
Two:
描述
题解
最开始拿到这道题,想半天只想到了暴力解题的思路,并不断尝试优化,但是始终无法AC,于是乎,百度了一下题解,发现需要用到一个我没有用过的数论知识——莫比乌斯反演,看来需要好好看看这个东西了。具体的题解官方给出了,十分详细,详细的我并不能完全悟透,还是看看代码吧。这里有两个代码,一个是我的智商所能达到的暴力解题思路(代码 One),另一个则是利用莫比乌斯反演得到的超牛逼的解法儿(代码 Two),数学家的世界我不懂~~~
这辈子,我最讨厌的人就是数学家、物理学家、化学家,给我的学生时代造成了多么大的心理阴影啊!
代码
One://#include <iostream> //#include <cstdio> // //using namespace std; // //const int MAXN = 1e5 + 10; // //int a[MAXN]; //int b[MAXN]; // //int gcd(int a, int b) //{ // if (!a || !b) // { // return a > b ? a : b; // } // for (int t; t = a % b, t; a = b, b = t); // return b; //} // //int main(int argc, const char * argv[]) //{ //// freopen("/Users/zyj/Desktop/input.txt", "r", stdin); // int n; // cin >> n; // // for (int i = 1; i <= n; i++) // { // scanf("%d", a + i); // } // for (int i = 1; i <= n; i++) // { // scanf("%d", b + i); // } // // int cnt = 0; // if (a[b[1]] == b[a[1]]) // { // cnt++; // } // for (int i = 1; i <= n; i++) // { // for (int j = i + 1; j <= n; j++) // { // int temp = (a[b[i]] == b[a[j]]) + (b[a[i]] == a[b[j]]); // if (temp && gcd(i, j) == 1) // { // cnt += temp; // } // } // } // // cout << cnt << endl; // // return 0; //}
Two:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int MAXN = 1e5 + 10; bool check[MAXN]; int prime[MAXN]; int mu[MAXN]; void Mobius() { memset(check, false, sizeof(check)); mu[1] = 1; int tot = 0; for (int i = 2; i <= MAXN; i++) { if (!check[i]) { prime[tot++] = i; mu[i] = -1; } for (int j = 0; j < tot; j++) { if (i * prime[j] > MAXN) { break; } check[i * prime[j]] = true; if (i % prime[j] == 0) { mu[i * prime[j]] = 0; break; } else { mu[i * prime[j]] = -mu[i]; } } } } int n; int a[MAXN]; int b[MAXN]; int vis[MAXN]; ll cal(int t) { ll ret = 0; for (int i = t; i <= n; i += t) { vis[b[a[i]]]++; } for (int i = t; i <= n; i += t) { ret += vis[a[b[i]]]; } for (int i = t; i <= n; i += t) { vis[b[a[i]]]--; } return ret; } int main() { Mobius(); while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) { scanf("%d", a + i); } for (int i = 1; i <= n; i++) { scanf("%d", b + i); } ll ans = 0; for (int i = 1; i <= n; i++) { ans += mu[i] * cal(i); } printf("%lld\n", ans); } return 0; }
参考
《莫比乌斯反演》相关文章推荐
- 【51NOD 1675】序列变换
- 51nod 1675 序列变换 (简单莫比乌斯)
- 51nod 1675 序列变换 莫比乌斯反演
- 51nod 1675 序列变换
- 51nod 1675 序列变换 莫比乌斯反演
- 51Nod - 1675 序列变换 mobius反演
- 51Nod 欢乐手速场1 B 序列变换[容斥原理 莫比乌斯函数]
- 51nod 欢乐手速场1(迎新春)-B序列变换(莫比乌斯反演)
- 51nod 1294 :修改数组 && HDU 5256:序列变换
- 51nod 1294 :修改数组 && HDU 5256:序列变换
- 51nod 序列变换 [容斥原理+莫比乌斯函数]【数论+组合数学】
- 51nod 1202 子序列的个数 dp
- 51nod 1483 化学变换 | 二进制 暴力
- [NOI2009]变换序列
- BZOJ 1562 [NOI2009]变换序列 (二分图匹配)
- BZOJ 1562 变换序列
- 51nod-1478 括号序列的最长合法子段
- 51nod 1202 子序列个数
- 51nod 1134 最长递增子序列(dp+二分)
- hdu5256【序列变换】【LIS】