题解:P11458 [USACO24DEC] All Pairs Similarity P
水个
记
于是我们只用管分母就好了,也就是要对于
以及
不考虑
对于容斥系数要求满足对于任意
然后就做完了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1<<20,mod = 1e9+7;
int n,K;
int a[N];
ll s1[N],s2[N];
ll V[21],C[21][21],inv[21];
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>n>>K;
for(int i = 1;i <= n;i++)
{
int x;cin>>x;
a[i] = x;
s1[x]++;
s2[x] += __builtin_popcount(x);
}
inv[1] = 1;
for(int i = 2;i <= K;i++) inv[i] = mod - mod/i*inv[mod%i]%mod;
for(int i = 0;i <= K;i++)
{
C[i][0] = 1;
for(int j = 1;j <= i;j++) C[i][j] = (C[i-1][j] + C[i-1][j-1])%mod;
}
V[K] = inv[K];
for(int i = K-1;i;i--)
{
V[i] = inv[i];
for(int j = i+1;j <= K;j++) V[i] = (V[i] + mod - V[j]*C[K-i][K-j]%mod)%mod;
}
for(int i = 1;i < (1<<K);i<<=1)
for(int j = 0;j < (1<<K);j += i<<1)
for(int k = 0;k < i;k++)
{
s2[i+j+k] += s2[j+k];
s1[i+j+k] += s1[j+k];
}
for(int i = 1;i < (1<<K);i++)
{
s2[i] = s2[i]*V[__builtin_popcount(i)]%mod;
s1[i] = s1[i]*V[__builtin_popcount(i)]%mod;
}
for(int i = 1;i < (1<<K);i<<=1)
for(int j = 0;j < (1<<K);j += i<<1)
for(int k = 0;k < i;k++)
{
s2[j+k] += s2[i+j+k];
s1[j+k] += s1[i+j+k];
}
for(int i = 1;i <= n;i++)
{
cout<<(__builtin_popcount(a[i])*s1[a[i]] + s2[a[i]]-n+mod)%mod<<"\n";
}
return 0;
}