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
备注:
30%的数据n≤4,m≤10,k≤10n \le 4,m \le 10,k \le 10n≤4,m≤10,k≤10
另有20%的数据k=0{k=0}k=0
70%的数据n≤1000,m≤1000,k≤1000n \le 1000,m \le 1000,k \le 1000n≤1000,m≤1000,k≤1000
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 mn≤109,m≤109,k≤105,1≤y≤n,1≤x≤m
分析
每个位置都有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; }