BZOJ2751 [HAOI2012] 容易题(easy)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2751
Description
为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:
有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值,是不是很简单呢?呵呵!
Input
第一行三个整数n,m,k分别表示数列元素的取值范围,数列元素个数,以及已知的限制条数。
接下来k行,每行两个正整数x,y表示A[x]的值不能是y。
Output
一行一个整数表示所有可能的数列的积的和对1000000007取模后的结果。如果一个合法的数列都没有,答案输出0。
快速幂就行了,把有限制的先算了再算没有限制的
Orz了云神的代码才终于明白,可怜蒟蒻我WA了5次,智商拙急啊。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define rep(i,l,r) for(int i=l; i<=r; i++) 5 #define clr(x,y) memset(x,y,sizeof(x)) 6 typedef long long ll; 7 using namespace std; 8 const int KPM = 1000000007; 9 const int maxn = 100010; 10 struct info{ 11 int p,v; 12 inline bool operator < (const info &_Tp) const{ 13 if (p != _Tp.p) return p < _Tp.p; 14 return v < _Tp.v; 15 } 16 }a[maxn]; 17 int n,m,k; 18 ll ans,sum,temp; 19 inline int read(){ 20 int ans = 0, f = 1; 21 char c = getchar(); 22 while (!isdigit(c)){ 23 if (c == '-') f = -1; 24 c = getchar(); 25 } 26 while (isdigit(c)){ 27 ans = ans * 10 + c - '0'; 28 c = getchar(); 29 } 30 return ans * f; 31 } 32 ll qpow(int x,int y){ 33 ll res = 1, b = x; 34 while (y){ 35 if(y & 1) res = res * b % KPM; 36 b = b * b % KPM; 37 y >>= 1; 38 } 39 return res; 40 } 41 int main(){ 42 n = read(); m = read(); k = read(); 43 rep(i,1,k) a[i].p = read(), a[i].v = read(); 44 sort(a+1,a+k+1); 45 sum = (ll) n*(n+1)/2 % KPM; ans = 1; temp = sum; 46 rep(i,1,k){ 47 if (a[i].p != a[i-1].p && i != 1){ 48 ans = ans * temp % KPM; temp = sum; m--; 49 } 50 if (a[i].p != a[i-1].p || a[i].v != a[i-1].v){ 51 temp -= a[i].v; if (temp < 0) temp += KPM; 52 } 53 } 54 m--; ans = ans * temp % KPM; ans = ans * qpow(sum,m) % KPM; 55 printf("%lld\n",ans); 56 return 0; 57 }