Description
给出一个m个数的序列,每个数可以是1~n中的任意一个数。再给出k个限制,每个限制形为x,y,表示第x个数不能是y。求所有可能的序列积的和。
序列积定义为序列中所有数的积。
n,m<=10^9,k<=10^5
Solution
很显然的,easy题就是easy。
若没有限制,那么答案就是
(n∗(n+1)2)m
有限制的话,求出每个有限制位置的数可以的和,然后乘起来,最后的部分用快速幂搞掂就好了。
Code
#include<map>
#include<cstdio>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 100005
using namespace std;
typedef long long ll;
const int mo=1000000000+7;
map<int,int> h,pd[N];
ll ans,sum,a[N];
int n,m,k,x,y,tot;
ll mi(ll x,int y) {
ll z=x;
for(y--;y;y/=2) {
if (y&1) (z*=x)%=mo;
(x*=x)%=mo;
}
return z;
}
int main() {
scanf("%d%d%d",&n,&m,&k);
sum=(ll)n*(n+1)/2%mo;
fo(i,1,k) {
scanf("%d%d",&x,&y);
if (!h[x]) h[x]=++tot;x=h[x];
if (pd[x][y]) continue;
(a[x]+=(ll)mo-y)%=mo;pd[x][y]=1;
}ans=mi(sum,m-tot);
fo(i,1,tot) (ans*=a[i]+sum)%=mo;
printf("%lld",ans);
}
Ps:离散化开了map作弊,有没有什么更好的办法?求带