[BZOJ 2751] && [HAOI2012] 容易题(easy)

来源:互联网 发布:电脑防护软件 编辑:程序博客网 时间:2024/05/07 18:28

发现蒟蒻只会刷这种容易题了囧

2751: [HAOI2012]容易题(easy)

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 882  Solved: 381
[Submit][Status]

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


想不到省选里也会有这种的水平题目。。。
说好听点叫倍增,说难听点叫快速幂?NOIP T1难度?
算了算了。。
很明显它的答案就是每一位(可以取到的数的和)的乘积  [嗯请注意运算优先顺序]
发现K很小对吧。。
所以改过的不会有很多。。
所以对于没有改过的(假设有k个),就是(n(n+1))^k
有改过的就是进来先对x快排一下,然后对于每一个x都统计一下就好了,反正也不会很大。。
Code:
const shuru='easy.in';  shuchu='easy.out';  maxn=100001;  modn=1000000007;  long=10007;vara,b:array[0..maxn] of int64;hash:array[0..long] of boolean;tmp,count,ans,now,step,n,m,k:int64;i,j,l:longint;procedure init;beginreadln(n,m,k);for i:=1 to k do readln(a[i],b[i]);end;procedure qsort(left,right:longint);var i,j,mid:longint;begini:=left; j:=right; mid:=a[(i+j) shr 1];repeatwhile a[i]<mid do inc(i);while a[j]>mid do dec(j);if i<=j then begintmp:=a[i]; a[i]:=a[j]; a[j]:=tmp;tmp:=b[i]; b[i]:=b[j]; b[j]:=tmp;inc(i); dec(j); end;until i>j;if j>left  then qsort(left,j);if i<right then qsort(i,right);end;procedure main;begininit;step:=n*(n+1) div 2;step:=step mod modn;qsort(1,k);i:=1;ans:=1;while (i<=k) dobeginj:=i;now:=step;fillchar(hash,sizeof(hash),false);while a[j+1]=a[j] do inc(j);for l:=i to j do beginif hash[b[l] mod long] then continue;hash[b[l] mod long]:=true;now:=now-b[l]; end;inc(count);ans:=(ans*now) mod modn;i:=j+1;end;m:=m-count;while (m>0) dobeginif (m and 1=1) then ans:=ans*step mod modn;m:=m shr 1;step:=step*step mod modn;end;writeln(((ans mod modn)+modn) mod modn);end;beginmain;end.   

0 0