[容斥原理]
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 }
698C.LRU
547C
概率dp
24D
No matter how you feel, get up , dress up , show up ,and never give up.