[容斥原理]

 1 ll pow(ll a,ll b,ll mod)
 2 {
 3     ll res=1;
 4    // if(a==0)    return res;
 5     while(b)
 6     {
 7         if(b&1)  res=(res*a)%mod;
 8         a=(a*a)%mod;
 9         b>>=1;
10     }
11     return res;
12 }
13 void init()
14 {
15     inv[1]=1;
16     for(int i=2;i<n;i++)//逆元
17         inv[i]=(mod-mod/i)*1ll*inv[mod%i]%mod;
18     F[0]=Finv[0]=1;
19     for(int i=1;i<n;i++)
20     {
21         F[i]=F[i-1]*i*1ll%mod;//阶乘
22         Finv[i]=Finv[i-1]*1ll*inv[i]%mod;//阶乘
23     }
24 }
25 int comb(int n,int m)//求Cnm
26 {
27     if(m<0||m>n)    return 0;
28     return F[n]*1ll*Finv[n-m]%mod*Finv[m]%mod;
29 }

 

 codeforces:

  839D. Winter is here

给一个数组,设他其中  gcd>1的子序列的价值为 gcd*(子序列长度),求所有子序列的价值总和。

设所有gcd=k的子序列价值之和为f[k]   cnt为数组中元素是k的倍数的个数

f[k]=cnt*2^(cnt-1)-  f[c]   (c是k的倍数)

这个序列包含了 gcd为k的倍数的 价值, 所以要减掉。

然后用map超时了 ,用 umap或者开个数组就可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <set>
 6 #include <queue>
 7 #include <stack>
 8 #include <string>
 9 #include <cstring>
10 #include <vector>
11 #include <map>
12 #include<ctime>
13 #include <unordered_map>
14 #define mem( a ,x ) memset( a , x ,sizeof(a) )
15 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
16 #define lson  l ,mid ,pos<<1
17 #define rson mid+1 ,r ,pos<<1|1
18 using namespace std;
19 typedef long long ll ;
20 typedef pair<int ,int> pii;
21 typedef pair<ll ,int> pli;
22 const int inf = 0x3f3f3f3f;
23 const ll mod=1e9+7;
24 const int N=100000+50;
25 int n,a[10*N];
26 unordered_map<int,int>mp;
27 int maxx=0,cnt=0;
28 ll f[10*N],inv[10*N],ans=0;
29 int main()
30 {
31     scanf("%d",&n);
32     for(int i=1;i<=n;i++)
33     {
34         scanf("%d",&a[i]);
35         maxx=max(maxx,a[i]);
36         mp[a[i]]++;
37     }
38     inv[0]=1;
39     for(int i=1;i<=n;i++)
40         inv[i]=(1ll*inv[i-1]*2)%mod;
41     for(int i=maxx;i>1;i--)
42     {
43         cnt=0;
44         for(int j=i;j<=maxx;j+=i)   cnt+=mp[j];
45         if(cnt==0)  continue;
46         f[i]=(cnt*inv[cnt-1])%mod;
47         for(int j=2*i;j<=maxx;j+=i)
48             f[i]=(f[i]-f[j]+mod)%mod;
49         ans=ans+(1ll*i*f[i])%mod;
50         ans%=mod;
51     }
52     printf("%lld\n",ans);
53 
54 
55     return 0;
56 }
View Code

 

  698C.LRU

  547C

 

概率dp

24D

posted @ 2020-05-26 14:34  kaike  阅读(180)  评论(0编辑  收藏  举报