ZOJ-3868-GCD Expectation(容斥)

GCD Expectation


Time Limit: 4 Seconds     
Memory Limit: 262144 KB



Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1,
x2,…,xm} (each nonempty subset has equal probability to be picked), and would like to know the expectation of [gcd(x1,
x2,…,xm)]k.

Note that gcd(x1, x2,…,xm) is the greatest common divisor of {x1,
x2,…,xm}.

Input

There are multiple test cases. The first line of input contains an integer
T
indicating the number of test cases. For each test case:

The first line contains two integers n, k (1 ≤ n,
k ≤ 106). The second line contains n integers
a
1, a2,…,an (1 ≤
ai ≤ 106).

The sum of values max{ai} for all the test cases does not exceed 2000000.

Output

For each case, if the expectation is E, output a single integer denotes
E · (2n - 1) modulo 998244353.

Sample Input

1
5 1
1 2 3 4 5

Sample Output

42

题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5480

题意 ,给出序列a[1],a[2]...a[i],求子序列 [gcd(x1x2,…,xm)]k.   的期望乘  (2n - 1)  ,   显然子序列个数有 (2n -
1) 个,那么其实就是所有子序列gcd的k次方求和啦

数据范围不超1e6,那么可以直接枚举gcd就好啦,dp[i]表示gcd为i的组数,从高到低枚举gcd,计算出i的倍数出现了m次,那么就有2^m-1组为i倍数的子序列,

显然,dp[i]=2^m-1-dp[i*2]-dp[i*3]-....;

//#include<bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const int MAXN = 1e6+7;
const int MOD = 998244353;
long long a[MAXN],dp[MAXN];
long long quick_pow(long long a,long long n)
{
    long long ans=1;
    while(n)
    {
        if(n&1)ans*=a,ans%=MOD;
        a=a*a%MOD;
        n>>=1;
    }
    return ans;
}
int main()
{
    int T,n,k,temp;
    cin>>T;
    int cas=1;
    while(T--)
    {
        memset(a,0,sizeof(a));
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&n,&k);
        int maxx=0,x;
        for(int i=0; i<n; ++i)
        {
            scanf("%d",&x);
            a[x]++;
            maxx=max(maxx,x);
        }
        long long ans=0;
        for(int i=maxx; i>=1; --i)
        {
            int cnt=0,temp=0;
            for(int j=i; j<=maxx; j+=i)
            {
                cnt+=a[j];
                temp=(temp-dp[j]+MOD)%MOD;
            }
            dp[i]=((quick_pow(2,cnt)-1)%MOD+temp)%MOD;
            ans=(ans+dp[i]*quick_pow(i,k)%MOD)%MOD;
        }
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-14 17:18:42

ZOJ-3868-GCD Expectation(容斥)的相关文章

zoj.3868.GCD Expectation(数学推导&gt;&gt;容斥原理)

GCD Expectation Time Limit: 4 Seconds                                     Memory Limit: 262144 KB Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, x2,…,xm} (each nonempty subset has equal probability to be pick

ZOJ 3868 GCD Expectation DP

dp[i] 表示公约数为i时有多少种组合 先预处理一遍dp[i]这是的dp[i]表示含有公约数i或者i的倍数的组合有多少个 再倒着dp dp[i] - = Sigma(dp[j]) (j是i的倍数 2i,3i,4i.....) 结果既为 Sigma[ dp[i]*pow(i,k) ] GCD Expectation Time Limit: 4 Seconds      Memory Limit: 262144 KB Edward has a set of n integers {a1, a2,.

ACM学习历程—ZOJ 3868 GCD Expectation(莫比乌斯 || 容斥原理)

Description Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, x2,…,xm} (each nonempty subset has equal probability to be picked), and would like to know the expectation of [gcd(x1, x2,…,xm)]k. Note that gcd(x1, 

Zoj 3868 GCD Expectation

给一个集合,大小为n , 求所有子集的gcd 的期望和 . 期望的定义为 这个子集的最大公约数的K次方 : 每个元素被选中的概率是等可能的 即概率 p = (发生的事件数)/(总的事件数); 总的事件数 = 2^n -1; 大小为n的集合的非空子集个数为2^n -1 期望 = p(i) *i; = 1*p(1) + 2*p(2) + ... +n*p(n); 设x发生的事件数为 dp[x] , 则上式可化简为: =1*dp[1]/(2^n-1) + 2*dp[2]/(2^n-1) + ... +

[暴力统计] zoj 3868 GCD Expectation

题意: 给n和k,求n个数的任意非空子集gcd的k次方的期望. 最后期望乘上2^n-1 思路: 因为取每个子集都是等概率,所以取出每个子集的概率是1/(2^n-1) 然而最后的答案是乘上2^n-1 所以其实求的就是每个非空子集的gcd的k次方的和. 然后就是求法了. 我们可以把题目转换成求gcd等于i的非空集合有多少个. gcd从Max枚举到1,求出答案. 对于每个i,设n个数中是i的倍数的数有x个. 那么gcd等于i的个数就是总共的 (2^x-1)个减去gcd等于j的个数,j是i的倍数. 因此

ZOJ 3233 Lucky Number 容斥

给你a数组和b数组 求x到y之间有多少个数至少被a中一个数整除并且至少不被b中一个数整除 容斥第一问很简单 第二问可以考虑反面 设满足被a中至少一个数整除的数有sum1个 在被a中至少一个数整除的前提下 被b中所有数整除的数有sum2 答案就是sum1-sum2 在dfs的时候溢出了 借鉴了某大牛的方法 #include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int

HDU 1695 GCD(容斥定理)

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7529    Accepted Submission(s): 2773 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y

HihoCoder - 1867: GCD (莫比乌斯容斥)

Sample Input 6 1 6 2 5 3 4 Sample Output 10 You are given a {1, 2, ..., n}-permutation a[1], a[2], ..., a[n]. How many pairs of integers (i, j) satisfy 1 ≤ i ≤ j ≤ n and gcd(i, j) = gcd(a[i], a[j]) = 1? Here gcd means greatest common divisor. Input F

zoj[3868]gcd期望

题意:求n个数组成的集合的所有非空子集的gcd的期望 大致思路:对于一个数x,设以x为约数的数的个数为cnt[x],所组成的非空集合个数有2^cnt[x]-1个,这其中有一些集合的gcd是x的倍数的,怎么求得最终结果呢?下面来说明过程. 令f[x] = 2^cnt[x]-1,表示以x为gcd的集合个数.令maxn为所有数的最大值,一开始f[maxn]=2^cnt[maxn]-1是肯定正确的.若从大到小更新f数组,类似数学归纳法,f[x]需要减去f[2x].f[3x].....f[px],px<=

hdu 1695 GCD 欧拉函数+容斥

题意:给定a,b,c,d,k x属于[1 , c],y属于[1 , d],求满足gcd(x,y)=k的对数.其中<x,y>和<y,x>算相同. 思路:不妨设c<d,x<=y.问题可以转化为x属于[1,c / k ],y属于[1,d/k ],x和y互质的对数. 那么假如y<=c/k,那么对数就是y从1到c/k欧拉函数的和.如果y>c/k,就只能从[ c/k+1 , d ]枚举,然后利用容斥.详见代码: /****************************