• ZOJ 3868 GCD Expectation


    GCD Expectation

    Time Limit: 4000ms
    Memory Limit: 262144KB
    This problem will be judged on ZJU. Original ID: 3868
    64-bit integer IO format: %lld      Java class name: Main
     

    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 nk (1 ≤ nk ≤ 106). The second line contains n integers a1, 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

    Source

    Author

    LIN, Xi
     
    解题:我们采取的是枚举gcd的策略
    真子集的个数为$2^{cnt}-1$个数
    但是我们发现,算我们枚举的gcd的时候,真正的gcd确实我们枚举的gcd的倍数
    所以要去重,利用容斥原理
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int mod = 998244353;
     5 const int maxn = 1000010;
     6 LL dp[maxn];
     7 int sum[maxn];
     8 LL quickPow(LL base,int index){
     9     LL ret = 1;
    10     while(index){
    11         if(index&1) ret = ret*base%mod;
    12         index >>= 1;
    13         base = base*base%mod;
    14     }
    15     return ret;
    16 }
    17 int main(){
    18     int kase,n,k,mxv,tmp;
    19     scanf("%d",&kase);
    20     while(kase--){
    21         scanf("%d%d",&n,&k);
    22         memset(sum,0,sizeof sum);
    23         for(int i = mxv = 0; i < n; ++i){
    24             scanf("%d",&tmp);
    25             sum[tmp]++;
    26             mxv = max(mxv,tmp);
    27         }
    28         LL ret = 0;
    29         for(int i = mxv; i > 0; --i){
    30             int cnt = dp[i] = 0;
    31             for(int j = i; j <= mxv; j += i){
    32                 dp[i] = (dp[i] - dp[j] + mod)%mod;
    33                 cnt += sum[j];
    34             }
    35             dp[i] = (dp[i] + quickPow(2,cnt) - 1)%mod;
    36             ret = (ret + dp[i]*quickPow(i,k))%mod;
    37         }
    38         printf("%lld
    ",ret);
    39     }
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    python操作MongoDB
    MongoDB操作——备忘录
    python中运行js代码—js2py
    糗事百科爬虫_基于线程池
    糗事百科_基于队列和多线程
    Django ModelForm组件
    Django补充(mark_safe,url反向解析)
    Django MiddleWare中间件
    Python常用模块 -- sys模块的常用用法
    Python常用模块 -- os模块常用用法
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4784679.html
Copyright © 2020-2023  润新知