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。
根据乘法分配律可以知道,答案就是把每一个位置所有可行的值的和乘起来。有限制的单独算,没有限制的快速幂。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=1000000007;
struct ban
{
int p,x;
bool operator < (const ban & bb) const
{
return p<bb.p||(p==bb.p&&x<bb.x);
}
}a[100010];
int pow(int x,int p)
{
int ret=1;
while (p)
{
if (p&1) ret=(LL)ret*x%mod;
x=(LL)x*x%mod;
p>>=1;
}
return ret;
}
int main()
{
int i,j,k,m,n,p,q,x,y,z,cnt=0,sum,ans=1,now=1;
scanf("%d%d%d",&n,&m,&k);
sum=(LL)n*(n+1)%mod*pow(2,mod-2)%mod;
for (i=1;i<=k;i++)
scanf("%d%d",&a[i].p,&a[i].x);
sort(a+1,a+k+1);
a[0]=(ban){-1,-1};
a[k+1]=(ban){-2,-2};
for (i=1;i<=k+1;i++)
{
if (a[i].p!=a[i-1].p)
{
ans=(LL)ans*now%mod;
cnt++;
now=sum;
}
if (a[i].p!=a[i-1].p||a[i].x!=a[i-1].x) now=((now-a[i].x)%mod+mod)%mod;
}
printf("%d\n",(LL)ans*pow(sum,m-cnt+1)%mod);
}