Codeforces Round #428 (Div. 2) ( 组合数学)

来源:互联网 发布:origin绘图软件下载 编辑:程序博客网 时间:2024/05/23 10:36

题目链接

题解:

组合数学:

Let cnt[i] be the number of such js that aj is divisible by i. Than cnt[i] is count of soliders with strength of i, 2i, 3i, ....

Let ans[i] be count of people in clans with gcd = i. To find ans[i] let's understand, how to find count of people in clans, in which every number is divided by i. If cnt[i] = c, it's

Let's calculate ans[i] from the end. Then ans[i] = cnt[i]·2cnt[i] - 1 - ans[2i] - ans[3i] - ....

Answer for problem's question is .

Asymptotics of solution is , where k is maximal value of ai.

ans[i]就是gcd为i的所有序列的元素个数之和,也就是题目中当gcd为d是的k之和。

代码如下:

#include <bits/stdc++.h>#define ll long longusing namespace std;const int maxn = 2e5 + 10;const int maxm = 1e6 + 10;const ll MOD = 1e9 + 7;ll ans[maxm],cnt[maxm];int a[maxn],n,vis[maxm];ll q_pow(ll x,int k){ll ret = 1;while(k > 0) {if(k & 1) ret  = ret * x % MOD;x = x * x % MOD;k >>= 1;}return ret;}int main(){scanf("%d",&n);int maxv = 0;for(int i = 1;i <= n;i++){scanf("%d",&a[i]);maxv = max(maxv,a[i]);vis[a[i]]++;}cnt[1] = n;for(int i = 2;i <= maxv;i++){for(int j = i;j <= maxv;j+=i){cnt[i] += vis[j];}}ll out = 0;for(int i = maxv;i >= 1;i--){if(cnt[i] <= 0) continue;ans[i] = cnt[i] * q_pow(2,cnt[i] - 1) % MOD;for(int j = i + i;j <= maxv;j+=i){ans[i] = (ans[i] - ans[j] + MOD) % MOD;}if(i > 1) out = (ans[i] * i + out) % MOD;}printf("%I64d\n",out);}



阅读全文
0 0
原创粉丝点击