zoj 3868 GCD Expectation(数学)

来源:互联网 发布:java线程第三版源码 编辑:程序博客网 时间:2024/06/05 14:40

ZOJ Problem Set - 3868
GCD Expectation

Time Limit: 4 Seconds      Memory Limit: 262144 KB

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

Note that gcd(x1x2,…,xm) is the greatest common divisor of {x1x2,…,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 nk (1 ≤ nk ≤ 106). The second line contains n integers a1a2,…,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

15 11 2 3 4 5

Sample Output

42

给出n k 给出n个数 求这n个数中所有非空子集最大公约数  期望值是gcd的k次方 最后用期望乘以 2^n-1
#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string.h>#include <string>#include <vector>#include <queue>#define MEM(a,x) memset(a,x,sizeof a)#define eps 1e-8#define MOD 998244353#define MAXN 1000010#define MAXM 100010#define INF 99999999#define ll long long#define bug cout<<"here"<<endl#define fread freopen("ceshi.txt","r",stdin)#define fwrite freopen("out.txt","w",stdout)using namespace std;int Read(){    char ch;    int a = 0;    while((ch = getchar()) == ' ' | ch == '\n');    a += ch - '0';    while((ch = getchar()) != ' ' && ch != '\n')    {        a *= 10;        a += ch - '0';    }    return a;}void Print(int a)    //Êä³öÍâ¹Ò{     if(a>9)         Print(a/10);     putchar(a%10+'0');}ll quick_mod(ll a,ll b){    ll ans=1;    while(b)    {        if(b&1)            ans=(ans*a)%MOD;        a=(a*a)%MOD;        b>>=1;    }    return ans;}ll a[MAXN];ll two[MAXN],expe[MAXN];//expe记录期望值void init(){    two[0]=1;    for(int i=1;i<MAXN;i++)        two[i]=(two[i-1]*2)%MOD;}int vis[MAXN],cnt[MAXN];int main(){//    fread;    init();    int tc;    scanf("%d",&tc);    while(tc--)    {        ll n,k;        scanf("%lld%lld",&n,&k);        MEM(vis,0);        MEM(cnt,0);        ll mx=0;        for(ll i=1;i<=n;i++)        {            scanf("%lld",&a[i]);            if(!vis[a[i]])            {                vis[a[i]]=1;                cnt[a[i]]=1;            }            else                cnt[a[i]]++;            mx=max(mx,a[i]);        }        expe[1]=1;        for(ll i=2;i<=mx;i++)            expe[i]=quick_mod(i,k);        for(ll i=1;i<=mx;i++)        {            for(ll j=i+i;j<=mx;j+=i)                expe[j]=(expe[j]-expe[i])%MOD;        }        ll ans=((two[n]-1)*expe[1])%MOD;        for(ll i=2;i<=mx;i++)        {            ll num=0;            for(ll j=i;j<=mx;j+=i)            {                if(vis[j]) num+=cnt[j];            }            ll x=((two[num]-1)*expe[i])%MOD;            ans=(ans+x)%MOD;//            cout<<i<<"  "<<ans<<endl;        }//        cout<<ans<<endl;        printf("%lld\n",(ans+MOD)%MOD);    }    return 0;}












0 0