1025 [HAOI2012]容易题(EASY) 组合数学

 链接:https://ac.nowcoder.com/acm/contest/26656/1025
来源:牛客网

题目描述

为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下: 
有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值,是不是很简单呢?呵呵!

输入描述:

第一行三个整数n,m,k分别表示数列元素的取值范围,数列元素个数,以及已知的限制条数。
接下来k行,每行两个正整数x,y表示A[x]的值不能是y。

输出描述:

一行一个整数表示所有可能的数列的积的和对1000000007取模后的结果。如果一个合法的数列都没有,答案输出0。
示例1

输入

复制
3 4 5
1 1
1 1
2 2
2 3
4 3

输出

复制
90

说明

样例解释
A[1]不能取1
A[2]不能去2、3
A[4]不能取3
所以可能的数列有以下12种
数列 积
2 1 1 1 2
2 1 1 2 4
2 1 2 1 4
2 1 2 2 8
2 1 3 1 6
2 1 3 2 12
3 1 1 1 3
3 1 1 2 6
3 1 2 1 6
3 1 2 2 12
3 1 3 1 9
3 1 3 2 18

备注:

30%的数据n≤4,m≤10,k≤10n \le 4,m \le 10,k \le 10n4,m10,k10
另有20%的数据k=0{k=0}k=0
70%的数据n≤1000,m≤1000,k≤1000n \le 1000,m \le 1000,k \le 1000n1000,m1000,k1000
100%的数据 n≤109,m≤109,k≤105,1≤y≤n,1≤x≤mn \le 10^9,m \le 10^9,k \le 10^5,1 \le y \le n,1 \le x \le mn109,m109,k105,1yn,1xm

分析

每个位置都有n种选择,

加入没有不能选择的数,答案就是:(n*(n-1)/2) ^ m

有了不能选择的数每个位置倒要删去对应的值,假设sum = (n * (n - 1) / 2 ) ,则每个位置对应的值为sum - Ebi

最终结果即为每项相乘。

set<pair<int,int>>s;可以用来去重

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
set<pair<int,int>> s;
map<int,int> mp;
ll mod = 1e9+7;
ll qmi(int a,int n) {
    ll ans = 1,base = a;
    while(n) {
        if(n & 1) ans = (ans * base) % mod;
        base = (base * base) % mod;
        n >>= 1;
    }
    return ans;
}

int main() {
    ll n,m,k,sum = 0;
    cin>>n>>m>>k;
    sum = (n * (n + 1) / 2) % mod;
    for(int i = 1;i<=k;i++) {
        int x,v;cin>>x>>v;
        if(s.count({x,v}))continue;
        mp[x] += v;
        s.insert({x,v});
    }
    ll res = qmi(sum,m - mp.size());
    map<int,int>::iterator it;
    for(it = mp.begin();it != mp.end();it ++ ) res = res * (sum - (it->second)) % mod;
    cout<<(res % mod + mod) % mod;
}

 

posted @ 2022-07-28 19:24  er007  阅读(119)  评论(0编辑  收藏  举报