bzoj2751[HAOI2012]容易题(easy) 数论,简单题

Posted Kaiser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2751[HAOI2012]容易题(easy) 数论,简单题相关的知识,希望对你有一定的参考价值。

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。

Sample Input

3 4 5
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

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 }

 

以上是关于bzoj2751[HAOI2012]容易题(easy) 数论,简单题的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2751: [HAOI2012]容易题(easy)

bzoj2751--[HAOI]2012容易题--组合(乘法原理)

bzoj2751[HAOI2012]容易题(easy) 数论,简单题

[HAOI2012] 容易题

[HAOI2012] 容易题

HAOI2012 容易题