很显然就是每一个位置可以取得数字之和都乘起来
然后限制并不多,也就是说大部分位置上的数字之和是相同的,然后用快速幂单独把这些的乘积搞出来,然后再单独算那些有限制的位置。
PS: 限制可能有重复,所以要特判一下,不过样例良心给了重复的
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define mod 1000000007
using namespace std;
int sc()
{
int i=0,f=1; char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}
struct W{int x,y;}a[100005];
int n,m,k;
ll sum,ans;
bool cmp(W x,W y)
{
return x.x==y.x?x.y<y.y:x.x<y.x;
}
ll cal(ll x,ll y)
{
ll ans=1;
for(;y;x=x*x%mod,y>>=1)
if(y&1)ans=ans*x%mod;
return ans;
}
int main()
{
n=sc(),m=sc(),k=sc();
for(int i=1;i<=k;i++)
a[i].x=sc(),a[i].y=sc();
sort(a+1,a+k+1,cmp);
for(int i=1;i<=k;i++)
if(a[i].x!=a[i-1].x)m--;
sum=(ll)n*(1+n)/2%mod;
ans=cal(sum,m);
for(int i=1,last;i<=k;i=last)
{
ll now=sum;
for(last=i;a[last].x==a[i].x;last++)
if(last==i||a[last].y!=a[last-1].y)
now=(now-a[last].y+mod)%mod;
ans=ans*now%mod;
}
cout<<ans;
return 0;
}