[HAOI2012] 容易题

有一个数列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 
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  mp;
struct limit {
    int x,y;
    bool operator < (const limit &b) const {
        return x==b.x?(y>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::iterator it=mp.begin();it!=mp.end();it++) {
        ans*=((n*(n+1)/2-it->second)%mod+mod)%mod;
        ans%=mod;
    }
    cout<

你可能感兴趣的:([HAOI2012] 容易题)