CF839D Winter is here

题目分析

\(g_i\)为序列\(gcd\)\(i\)的个数

可以列出一个初始值\(g_i=2^{num_i}-1,num_i\)为因数有\(i\)的个数

但这样明显会算重复,对于\(\forall j,j\mid i\) ,都会有重复的

\(g_i=2^{num_i}-1-\sum\limits_{j\mid i}g_j\)

\(但对于长度,我们重新定义g_i为序列gcd为i的数的个数\)

\(g_i=\sum\limits_{i=0}^{num_i}i\times\binom{num_i}{i}-\sum\limits_{j\mid i}g_j\)

\(g_i=\sum\limits_{i=0}^{num_i}num_i\times\binom{num_i-1}{i-1}-\sum\limits_{j\mid i}g_j\)

\(g_i=num_i\times\sum\limits_{i=0}^{num_i}\binom{num_i-1}{i-1}-\sum\limits_{j\mid i}g_j\)

\(g_i=num_i\times\sum\limits_{i=1}^{num_i}\binom{num_i-1}{i-1}-\sum\limits_{j\mid i}g_j\)

\(g_i=num_i\times\sum\limits_{i=0}^{num_i-1}\binom{num_i-1}{i}-\sum\limits_{j\mid i}g_j\)

\(g_i=num_i\times2^{num_i-1}-\sum\limits_{j\mid i}g_j\)

\(最后计数即可\)

#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9+7;
long long x;
long long num[1000005];
int cnt; 
long long Pow(int a, int b, int p) {
    long long ans = 1;
    long long base = a;
    base %= p;

    while (b) {
        if (b & 1) {
            ans *= base;
            ans %= p;
        }

        base *= base;
        base %= p;
        b >>= 1;
    }

    return ans;
}
int n,m;
long long g[1000005];
long long ans=0;
signed main() {
    scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&x);
		for(int j=1;j*j<=x;j++)
		{
			if(x%j==0)
			{
				num[j]++;
				if(j!=(x/j))
				{
					num[x/j]++;
				}	
			}
		}
	 } 
	for(int i=1000000;i>=2;i--)
	{
		if(!num[i])
		{
			continue;
		}
		
		g[i]=(num[i]*Pow(2,num[i]-1,MOD)%MOD)%MOD;
		for(int j=2*i;j<=1000000;j+=i)
		{
			g[i]=(g[i]-g[j]+MOD)%MOD;
		}
	
		ans=(ans+(g[i]*i%MOD))%MOD;
	}
	printf("%lld",ans); 
}

posted @ 2021-11-25 21:50  kid_magic  阅读(33)  评论(0编辑  收藏  举报