有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值
n<=10^9,m<=10^9,k<=10^5,1<=y<=n,1<=x<=m
Solution
还真是个容易题
首先每个位置对答案的贡献独立,那么我们可以把顺序换一下
先考虑所有不受限制的位置,假设有 (m-tot) 个,那么它们的贡献是 ((n(n+1)/2)^{m-tot})
在考虑受限的位置,一个位置不取哪些数,如果它们的和为 (s),这个位置的贡献就是 (n(n+1)/2 - s)
最后都乘起来即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int mod = 1000000007;
const int N = 1000005;
#define modulo mod
ll qpow(ll p,ll q) {
ll r = 1;
for(; q; p*=p, p%=modulo, q>>=1) if(q&1) r*=p, r%=modulo;
return r;
}
int n,m,k;
map <int,int> mp;
struct limit {
int x,y;
bool operator < (const limit &b) const {
return x==b.x?(y<b.y):(x<b.x);
}
bool operator != (const limit &b) const {
return x!=b.x || y!=b.y;
}
} l[N];
signed main() {
ios::sync_with_stdio(false);
cin>>n>>m>>k;
for(int i=1;i<=k;i++) {
int x,y;
cin>>x>>y;
l[i].x=x;
l[i].y=y;
}
sort(l+1,l+k+1);
for(int i=1;i<=k;i++) {
if(l[i]!=l[i-1]) mp[l[i].x]+=l[i].y;
}
int ans=qpow((n*(n+1)/2)%mod,m-mp.size());
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++) {
ans*=((n*(n+1)/2-it->second)%mod+mod)%mod;
ans%=mod;
}
cout<<ans;
}