欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

2017 多校2 hdu 6053 TrickGCD

发布时间:2023/12/31 编程问答 36 豆豆
生活随笔 收集整理的这篇文章主要介绍了 2017 多校2 hdu 6053 TrickGCD 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

2017 多校2 hdu 6053 TrickGCD

题目:

You are given an array \(A\) , and Zhu wants to know there are how many different array \(B\) satisfy the following conditions?

  • \(1≤B_i≤A_i\)
  • For each pair(\(l , r) (1≤l≤r≤n) , gcd(bl,bl+1...br)≥2\)

Input

The first line is an integer \(T(1≤T≤10)\) describe the number of test cases.

Each test case begins with an integer number n describe the size of array \(A\).

Then a line contains \(n\) numbers describe each element of \(A\)

You can assume that \(1≤n,A_i≤10^{5}\)

Output

For the \(k\)th test case , first output "Case #\(k\): " , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod \(10^{9}+7\)

思路:

枚举\(g = gcd(b_1,b_2,....,b_n)\),
那么\(gcd为g\)的倍数的答案就是\(\prod_{i=1}^{n}\frac{A_i}{g}\)
每次暴力计算是不行的,想到一个数在\(g到2g-1\)除以g结果是不变的
所以可以预处理区间数字个数的前缀和,\(O(nlogn)\)类似素数筛法预处理出每个\(g\)的答案
现在要计算\(gcd为g\)的答案,我们从大到小枚举,同时更新它的约数的答案,就可以保证不重复了
从小到大枚举过去就要用到莫比乌斯函数去计算了
\(令F(i)为gcd为i的倍数的方案数,f(i)为gcd为i的方案数\)
\(F(i) = \sum_{i|d}^{}{f(d)} \rightarrow f(i) = \sum_{i|d}u(\frac{d}{i})F(d)\)
代码贴的是比赛时过的姿势

#include<bits/stdc++.h> using namespace std; typedef pair<int,int> P; typedef long long LL; const int mod = 1e9 + 7; const int N = 1e5 + 10; vector<int> v[N]; int n; int sum[N],ans[N]; void init(){for(int i = 2;i < N;i++){for(int j = i;j < N;j+=i) v[j].push_back(i);} } int qpow(int x,int y){int ans = 1;while(y){if(y&1) ans = 1LL* ans * x % mod;x = 1LL * x * x % mod;y >>= 1;}return ans; } int main(void) {init();int T, x;int cas = 1;cin>>T;while(T--){memset(sum, 0, sizeof(sum));scanf("%d",&n);int mi = N;for(int i = 1;i <= n;i++) {scanf("%d",&x);mi = min(x,mi);sum[x]++;}for(int i = 1;i < N;i++) sum[i]+=sum[i-1];for(int i = 2;i <= mi;i++){ans[i] = 1;for(int j = i;j < N;j+=i){int l = j + i - 1 > N - 1?N-1:j + i - 1;ans[i] = 1LL * ans[i] * qpow(j / i,sum[l] - sum[j - 1]) % mod;}}int res = 0;for(int i = mi;i >= 2;i--){res = (res + ans[i])%mod;for(int j = 0;j < v[i].size();j++) ans[v[i][j]] = (ans[v[i][j]] - ans[i] + mod)%mod;}printf("Case #%d: %d\n",cas++,res);}return 0; }

转载于:https://www.cnblogs.com/jiachinzhao/p/7267453.html

总结

以上是生活随笔为你收集整理的2017 多校2 hdu 6053 TrickGCD的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。