bzoj2751 [HAOI2012]容易题(easy)

来源:互联网 发布:淘宝包邮规则 编辑:程序博客网 时间:2024/04/29 07:52

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 51 11 12 22 34 3

Sample Output

90

Hint

样例解释

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<=10
另有20%的数据k=0
70%的数据n<=1000,m<=1000,k<=1000
100%的数据 n<=109,m<=109,k<=105,1<=y<=n,1<=x<=m

Key To Problem

应该算是比较简单的题了吧
设第i个数可以取的数为aij,则所求即为Πmi=1(Σnj=1aij)
之后就很好求啦,具体看代码

Code

#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define N 100010#define MOD 1000000007using namespace std;typedef long long ll;struct node{    int a;    ll b;};node s[N];int m,k,top;ll sum[N];ll ans,n;int cmp(const void *x,const void *y){    int s1=(*(node *)x).a;    int s2=(*(node *)y).a;    ll k1=(*(node *)x).b;    ll k2=(*(node *)y).b;    if(s1==s2)    {        if(k1>k2)            return 1;        return -1;    }    return s1-s2;}ll pow(ll x,int y){    ll ans=1;    while(y)    {        if(y&1)            ans=(ans*x)%MOD;        x=(x*x)%MOD;        y>>=1;    }    return ans;}int main(){//  freopen("easy.in","r",stdin);//  freopen("easy.out","w",stdout);    cin>>n>>m>>k;    for(int i=1;i<=k;i++)        scanf("%d%d",&s[i].a,&s[i].b);    qsort(s+1,k,sizeof(s[0]),cmp);    for(int i=1;i<=k;i++)    {        if(s[i].a == s[i-1].a && s[i].b == s[i-1].b)            continue;        if(s[i].a != s[i-1].a)            top++;        sum[top] = (sum[top]+s[i].b)%MOD;    }    ll t=((1+n)*n/2)%MOD;    ans=pow(t,m-top);    for(int i=1;i<=top;i++)        ans=(ans*(t-sum[i]+MOD))%MOD;    cout<<ans<<endl;    return 0;}
0 0
原创粉丝点击