记录编号 56549 评测结果 AAAAAAAAAA
题目名称 [HAOI 2012]容易题 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.174 s
提交时间 2013-03-31 16:33:55 内存使用 5.44 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const long long MOD=1000000007;//模这个数
//若干个(1~n)乘起来,若干个有限制的
long long n,m,k;
//n是取值范围,m是数列元素个数,k是限制条数
long long nsum;//1~n求和
long long lsum;//有限制的元素个数
class PAIR{
public:
	long long x,y;
};//表示一条限制:A[x]不等于y
bool cmp(PAIR a,PAIR b){
	if(a.x!=b.x) return a.x<b.x;
	return a.y<b.y;
}
PAIR s[100001];//最初读的限制
long long limit[100001]={0};//最终科学的限制
//这里面存放的每一项都代表扣剩下的值
void read(void){
	scanf("%lld%lld%lld",&n,&m,&k);
	long long i;
	for(i=0;i<k;i++){
		scanf("%lld%lld",&s[i].x,&s[i].y);
	}
}
void getsum(void){//尼玛求个1~n都这么麻烦
	long long temp;
	if(n&1){//奇数
		temp=n;
		temp*=(n+1)/2;
		nsum=temp;
	}
	else{
		temp=(n+1);
		temp*=(n/2);
		nsum=temp;
	}
}
bool getlim(void){
	//对原始的限制进行整理
	if(k==0){
		lsum=0;
		return 1;
	}
	sort(s,s+k,cmp);
	int i;
	lsum=0;
	limit[lsum]=s[0].y;
	for(i=1;i<k;i++){
		if(s[i].x==s[i-1].x&&s[i].y==s[i-1].y) continue;
		if(s[i].x!=s[i-1].x) lsum++;//对不同元素的限制
		limit[lsum]+=s[i].y;
		if(limit[lsum]>nsum) return 0;
	}
	lsum++;
	//最终的lsum就是个数
	for(i=0;i<lsum;i++) limit[i]=nsum-limit[i];
	return 1;
}
long long quickpow(long long x,long long y){//x^y%MOD
	long long ans=1;
	long long temp=x;
	while(y){
		if(y&1) ans=ans*temp%MOD;//奇数
		temp=temp*temp%MOD;
		y>>=1;
	}
	return ans;
}
long long calc_limit(void){
	long long ans=1;
	int i;
	for(i=0;i<lsum;i++){
		ans*=limit[i]%MOD;
		ans%=MOD;
	}
	return ans;
}
int main(){
	freopen("easy.in","r",stdin);
	freopen("easy.out","w",stdout);
	read();
	getsum();
	bool flag=getlim();
	if(!flag){
		printf("0\n");
		return 0;
	}
	long long ans1=calc_limit();
	long long ans2=quickpow(nsum%MOD,m-lsum);
	long long ans=ans1*ans2%MOD;
	printf("%lld\n",ans);
	return 0;
}