答案是求合法序列的积的和,其实就是每个位置的合法值的和的积,即
(可以把前m-1个位置相同的式子提出来,发现乘的就是第m个位置的合法值的和,以此类推。)这样的话,虽然位置有10e9个,但是有限制的位置最多10e5个,剩下的位置的合法值的和都是sum(n*(n+1)/2),可以用快速幂进行计算,对于有限制的位置单个计算(排序后即可)。时间就可以过了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 1000000007
#define ll long long
using namespace std;
int const N=100005;
int n,m,k;
ll ans=1;
struct node{
int pos,val;
}a[N];
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
int qpow(ll a,int b){
ll t=1;
while(b){
if(b&1) t=(t*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return t;
}
bool cmp(node x,node y){
return (x.pos==y.pos)?x.val<y.val:x.pos<y.pos;
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();k=read();
for(int i=1;i<=k;i++) a[i].pos=read(),a[i].val=read();
sort(a+1,a+k+1,cmp);
int tot=m;
int sum=(ll)n*(n+1)/2%mod,tmp=1;
for(int i=1;i<=k;i++){
if(a[i].pos!=a[i-1].pos) tot--,ans=(ans*tmp)%mod,tmp=sum;
if(a[i].pos!=a[i-1].pos||a[i].val!=a[i-1].val){
tmp-=a[i].val;
if(tmp<0) tmp+=mod;
}
}
ans=(ans*tmp)%mod;
printf("%lld",ans*qpow(sum,tot)%mod);
return 0;
}