hdu 6053 TrickGCD [2017 Multi-University Training Contest
来源:互联网 发布:金字塔期货交易软件 编辑:程序博客网 时间:2024/05/24 05:39
点击打开题目
题意: 给你一个序列a,求满足对于所有l, r都有gcd(b[l], ... , b[r]) >= 2并且bi <= ai的b序列的数量.
分析: 先枚举gcd的值, 然后利用前缀和快速算出a[i]/g = c(c = 1, 2, 3, ...)的个数, 然后用快速幂, 快速算出gcd为g的时候的值, 最后用容斥筛选(或者用莫比乌斯函数).
代码1[容斥]:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>#include<cmath>typedef long long ll;const int maxn = 1e5 + 10;const ll mod = 1e9 + 7;using namespace std;int a[maxn], sum[maxn];ll dp[maxn];ll qmod(ll x, ll y) { ll ans = 1; while(y) { if(y & 1) ans = ans * x % mod; x = x * x % mod; y /= 2; } return ans;}int main() { int n, t, x, v = 1; scanf("%d", &t); while(t--) { scanf("%d", &n); memset(a, 0, sizeof a); memset(sum, 0, sizeof sum); memset(dp, 0, sizeof dp); for(int i = 0; i < n; i++) { scanf("%d", &x); a[x]++; } for(int i = 1; i < maxn; i++) { sum[i] = sum[i - 1] + a[i]; } ll a, b; int j; for(int i = 2; i <= 100000; i++) { if(sum[i - 1] > 0) break; dp[i] = 1; for(j = i + i; j <= 100000; j += i) { if(j + i > 100000) b = sum[100001] - sum[j - 1]; else b = sum[j + i - 1] - sum[j - 1]; a = j / i; dp[i] = dp[i] * qmod(a, b) % mod; } } for(int i = 100000; i >= 2; i--) { for(int j = i + i; j <= 100000; j += i) { dp[i] = (dp[i] - dp[j] + mod) % mod; } } ll ans = 0; for(int i = 2; i < maxn; i++) { ans = (ans + dp[i]) % mod; //if(dp[i]) printf("%d %lld\n", i, dp[i]); } printf("Case #%d: %lld\n", v++, ans); } return 0;}/*12100000 100000Case #1: 920698472*/
代码2[莫比乌斯函数]:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>#include<cmath>typedef long long ll;const int maxn = 1e5 + 10;const ll mod = 1e9 + 7;using namespace std;int a[maxn], sum[maxn], mu[maxn];ll dp[maxn];void getmu() { for(int i = 1; i <= maxn; i++) { int t = i == 1 ? 1 : 0; int d = t - mu[i]; mu[i] = d; for(int j = i + i; j <= maxn; j += i) { mu[j] += d; } }}ll qmod(ll x, ll y) { ll ans = 1; while(y) { if(y & 1) ans = ans * x % mod; x = x * x % mod; y /= 2; } return ans;}int main() { int n, t, x, v = 1; memset(mu, 0, sizeof mu); getmu(); scanf("%d", &t); while(t--) { scanf("%d", &n); memset(a, 0, sizeof a); memset(sum, 0, sizeof sum); memset(dp, 0, sizeof dp); for(int i = 0; i < n; i++) { scanf("%d", &x); a[x]++; } for(int i = 1; i < maxn; i++) { sum[i] = sum[i - 1] + a[i]; } ll a, b; int j; for(int i = 2; i <= 100000; i++) { if(sum[i - 1] > 0) break; dp[i] = 1; for(j = i + i; j <= 100000; j += i) { if(j + i > 100000) b = sum[100001] - sum[j - 1]; else b = sum[j + i - 1] - sum[j - 1]; a = j / i; dp[i] = dp[i] * qmod(a, b) % mod; } } ll ans = 0; for(int i = 2; i < maxn; i++) { ans = (ans - mu[i] * dp[i] + mod) % mod; } printf("Case #%d: %lld\n", v++, ans); } return 0;}
阅读全文
0 0
- hdu 6053 TrickGCD [2017 Multi-University Training Contest
- HDU 6053 TrickGCD(分块+容斥)——2017 Multi-University Training Contest
- 2017 Multi-University Training Contest 2 && HDOJ 6053 TrickGCD 【容斥+莫比乌斯函数】
- HDU 3068 2017 Multi-University Training Contest
- HDU 6034 & 2017 Multi-University Training Contest
- hdu 6034 2017 Multi-University Training Contest
- HDU 3065 2017 Multi-University Training Contest
- HDU 6047 2017 Multi-University Training Contest
- HDU 6052 2017 Multi-University Training Contest
- HDU 6058 2017 Multi-University Training Contest
- HDU 6078 2017 Multi-University Training Contest
- hdoj 6053(2017 Multi-University Training Contest
- [莫比乌斯函数][分段] hdu6053 TrickGCD (2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 简单了解巴克斯范式
- jQuery实现Ajax的封装
- 1001.Is Derek lying?
- 在HTML中使用JavaScript(总结自JavaScript高级程序设计)
- 离散事件模拟-银行管理
- hdu 6053 TrickGCD [2017 Multi-University Training Contest
- Ubuntu 14.04的基本配置
- HDU 6053 TrickGCD DP(筛法)
- 练习(三)
- session共享机制
- 程序员眼中世界上最远的距离
- Android 性能优化<九> RecyclerView替代Listview用法
- js基础 事件基础一
- C++实现顺序表基本函数以及增删查改