Description
为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:
有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值,是不是很简单呢?呵呵!
有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值,是不是很简单呢?呵呵!
Input
第一行三个整数n,m,k分别表示数列元素的取值范围,数列元素个数,以及已知的限制条数。
接下来k行,每行两个正整数x,y表示A[x]的值不能是y。
接下来k行,每行两个正整数x,y表示A[x]的值不能是y。
Output
一行一个整数表示所有可能的数列的积的和对1000000007取模后的结果。如果一个合法的数列都没有,答案输出0。
Sample Input
3 4 5
1 1
1 1
2 2
2 3
4 3
1 1
1 1
2 2
2 3
4 3
Sample Output
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
样例解释
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
HINT
数据范围
30%的数据n<=4,m<=10,k<=10
另有20%的数据k=0
70%的数据n<=1000,m<=1000,k<=1000
100%的数据 n<=109,m<=109,k<=105,1<=y<=n,1<=x<=m
Source
答案显然是这个
那么只要将限制排序,计算有限制的位置的和,乘起来
再乘上没有限制的(用快速幂)
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdio> 6 7 #define mod 1000000007 8 #define N 100007 9 #define ll long long 10 using namespace std; 11 inline ll read() 12 { 13 ll x=0,f=1;char ch=getchar(); 14 while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();} 15 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 19 ll n,m,k,num; 20 ll zhi[N],inx; 21 struct Node 22 { 23 ll x,y; 24 }a[N]; 25 26 bool operator<(Node x,Node y) 27 { 28 if (x.x==y.x) return x.y<y.y; 29 else return x.x<y.x; 30 } 31 ll ksm(ll a,int b) 32 { 33 ll res=1; 34 while(b) 35 { 36 if (b%2==1) res=(res*a)%mod; 37 a=(a*a)%mod; 38 b>>=1; 39 } 40 return res; 41 } 42 int main() 43 { 44 m=read(),n=read(),k=read(); 45 num=(1+m)*m/2;num%=mod; 46 for (int i=1;i<=k;i++) 47 a[i].x=read(),a[i].y=read(); 48 sort(a+1,a+k+1); 49 for (int i=1;i<=k;i++) 50 { 51 if (a[i].x==a[i-1].x&&a[i].y==a[i-1].y) continue; 52 if (a[i].x==a[i-1].x) zhi[inx]-=a[i].y; 53 else zhi[++inx]=num-a[i].y; 54 } 55 for (int i=1;i<=k;i++)zhi[i]=(zhi[i]%mod+mod)%mod; 56 n=n-inx; 57 ll ans=ksm(num,n); 58 for (int i=1;i<=inx;i++) 59 ans=(ans*zhi[i])%mod; 60 printf("%lld",ans); 61 }