HAOI2012 容易题
题目链接:戳我
就是乘法分配律。。。
但是一定要注意判重+判断输入的值是否都在n里面+谨防爆int!!!!
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define MAXN 1000010
#define mod 1000000007
using namespace std;
int n,m,k,cnt;
long long tot,ans;
map<int,int>fw;
map<pair<int,int>,int>done;
struct Node{int pos,sum;}node[MAXN];
inline bool cmp(struct Node x,struct Node y){return x.pos<y.pos;}
inline long long fpow(int x,int y)
{
long long cur_ans=1;
x%=mod;
while(y)
{
if(y&1) cur_ans=1ll*cur_ans*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return cur_ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
freopen("ce.out","w",stdout);
#endif
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
scanf("%d%d",&node[i].pos,&node[i].sum);
if(done[make_pair(node[i].pos,node[i].sum)]||node[i].sum>n)
{i--,k--;continue;}
if(!fw[node[i].pos]) cnt++;//cnt表示有限制的位置的个数
fw[node[i].pos]=1;
done[make_pair(node[i].pos,node[i].sum)]=1;
}
sort(&node[1],&node[k+1],cmp);
tot=(1ll*(1+n)*n/2)%mod;
ans=fpow(tot,m-cnt)%mod;
if(cnt==1)
{
long long cur_sum=tot;
for(int i=1;i<=k;i++)
cur_sum=(1ll*cur_sum+mod-node[i].sum)%mod;
ans=1ll*cur_sum*ans%mod;
}
else
{
long long cur_sum=0;
for(int i=1;i<=k+1;i++)
{
if(i!=1&&node[i].pos!=node[i-1].pos)
{
ans=1ll*ans*(1ll*tot+mod-cur_sum)%mod;
cur_sum=node[i].sum;
}
else cur_sum=(1ll*cur_sum+node[i].sum)%mod;
}
}
printf("%lld\n",ans%mod);
return 0;
}