题目:BZOJ2751
解析:
当
k
=
0
k=0
k=0时根据乘法分配律,答案为:
∏
i
=
1
n
n
∗
(
n
+
1
)
2
\prod _{i=1}^{n}\frac{n*(n+1)}{2}
i=1∏n2n∗(n+1)
有了限制后,答案变为
∏
i
=
1
n
−
k
n
∗
(
n
+
1
)
2
∗
(
∏
i
=
1
k
n
∗
(
n
+
1
)
2
−
s
u
m
[
i
]
)
\prod _{i=1}^{n-k}\frac{n*(n+1)}{2} *(\prod _{i=1}^{k}\frac{n*(n+1)}{2}-sum[i])
i=1∏n−k2n∗(n+1)∗(i=1∏k2n∗(n+1)−sum[i])
考虑到
k
≤
1
0
5
k\le10^5
k≤105可以直接暴力求,其余部分用快速幂求得。
答案:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1000000007;
const int Max=100010;
int n,m,k,ans,s,sum[Max],tot,b[Max];
map<int,int>v;
map<int,bool>vis[Max];
struct shu{
int pos,num;
friend inline bool operator<(const shu&a,const shu&b){return a.pos==b.pos?a.num<b.num:a.pos<b.pos;}
friend inline bool operator==(const shu&a,const shu&b){return a.pos==b.pos&&a.num==b.num;}
}a[Max];
inline int get_int()
{
int x=0,f=1;char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline int ksm(int a,int b)
{
int ans=1;
a%=mod;
while(b)
{
if(b&1) ans=(ans*a)%mod;
b>>=1,a=(a*a)%mod;
}
return ans;
}
signed main()
{
n=get_int(),m=get_int(),k=get_int();
int siz=0;
for(int i=1;i<=k;i++) a[i].pos=get_int(),a[i].num=get_int();
sort(a+1,a+k+1);k=unique(a+1,a+k+1)-a-1; //去重
for(int i=1;i<=k;++i){
if(a[siz].pos^a[i].pos)a[++siz]=a[i];
else (a[siz].num+=a[i].num)%=mod;
}
ans=ksm(n*(n+1)/2,m-siz);
for(int i=1;i<=siz;i++)
ans=(ans*((n*(n+1)/2-a[i].num)%mod))%mod;
cout<<ans<<"\n";
return 0;
}