Codeforces 167 div2 D Dima and Two Sequences

吐槽:B题因为没写long long WA两次就忍了,40分钟开始干D题,却花了1小时学习set和map  》_《

只会用C的伤不起啊。。。竟然把set和map的作用搞混了我了个去。。。

set不能存相同的元素是吗??那为什么还要搞count()函数啊!!!

调了半个小时楞没出来s.count(x)啊!!!无力吐槽了。。

另外吐槽下作者- -。。pretest 3就开始上100的数据了,要死啊。。

 

================昏割线===========================

 

设S(x)为坐标等于x的点的个数,很显然ans=( S(x1)! * S(x2)! * ...S(xm)! )%m

问题是有两个点相同的情况,在此题中只可能一种情况即Ai=Bi。

由于Ai=Bi,交换(Ai,i)(Bi,i)不产生新的排列,故ans/=2.

设有k对Ai=Bi 那么ans=( ( S(x1)! * S(x2)! *.....S(xm)! ) / (2^k) )%m

由于对于每一对Ai=Bi,S(Ai)>=2 所以可以把2先全部除掉,转换成全是乘法的运算,然后取余。

#include<cstdio>
#include<map>
#define X 100010
using namespace std;
int a[X],b[2*X];
map<int,int>g;
int main(){
	int i,j,n,m,k,x,cnt,top;
	long long as,tmp;
	as=1,top=1,cnt=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&x);
		if(!g[x])g[x]=top++;
		b[g[x]]++;
		a[i]=x;
	}
	for(i=1;i<=n;i++){
		scanf("%d",&x);
		if(!g[x])g[x]=top++;
		b[g[x]]++;
		if(a[i]==x)cnt++;
	}
	scanf("%d",&m);
	for(i=1;i<top;i++)
		if(b[i]){
			for(tmp=1;b[i];b[i]--)
				if(b[i]%2==0&&cnt)  tmp=(tmp*b[i]/2)%m,cnt--;				
				else 			    tmp=(tmp*b[i])%m;
			as=(as*tmp)%m;
		}
	printf("%I64d\n",as);
	return 0;
}


 

你可能感兴趣的:(Codeforces 167 div2 D Dima and Two Sequences)