容易题(数论)
容易题
题目大意
有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和mod 1000000007的值,是不是很简单呢?呵呵!
solution
容易题
根据我们数学刚刚学的分步乘法原理
没有限制的话那么总的方案数量\((1+2+3+……+n)^m\)
记录一下不能取到的值的\(tot\)
然后统计答案的时候把这个值换成\({\frac{(n(n-1))}{2}}\)\(-tot\)
对于剩下的点\(({\frac{(n(n-1))}{2}})^{m-cnt}\)
用快速幂预处理一下,然后累乘出结果就行了
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define int long long
using namespace std;
const int mod=1e9+7;
const int maxn=100005;
int sum[maxn];
struct node{
int x,y;
}a[maxn];
inline int read(){
int x=0,w=1;
char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*w;
}
inline bool cmp(node a,node b){
if(a.x==b.x)
return a.y<b.y;
else
return a.x<b.x;
}
inline int power(int x,int y,int mod){
int res=1;
while(y){
if(y&1)
res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
int n,m,k;
signed main(){
int ans=0;
n=read(),m=read(),k=read();
int sigma=(n*(n+1)>>1)%mod;
for(int i=1;i<=k;i++)
a[i].x=read(),a[i].y=read();
sort(a+1,a+1+k,cmp);
int cnt=0;
for(int i=1;i<=k;i++){
if(a[i].x!=a[i-1].x)
sum[++cnt]=sigma;
else
if(a[i].y==a[i-1].y)
continue;
sum[cnt]=(sum[cnt]-a[i].y+mod)%mod;
}
ans+=power(sigma,m-cnt,mod);
for(int i=1;i<=cnt;i++)
ans=(ans*sum[i]+mod)%mod;
cout<<ans<<'\n';
return 0;
}
风吹过,我来过~