记录编号 317948 评测结果 AAAAAAAAAA
题目名称 [HEOI 2015]公约数数列 最终得分 100
用户昵称 GravatarLOSER 是否通过 通过
代码语言 C++ 运行时间 4.442 s
提交时间 2016-10-08 18:54:26 内存使用 17.46 MiB
显示代码纯文本
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
#define maxn 100010
#define maxq 1010
#define LL long long
map<LL,LL> q[maxq];
LL m,n,a[maxn],data,num[maxq];
LL GCD(LL a,LL b){return b==0?a:GCD(b,a%b);}
#define pos(x) Belong[x]
LL Xor[maxq][maxq],gcd[maxq][maxq];
LL Belong[maxn],size,L[maxq],R[maxq],sum[maxq];
void Makeblock(){
	size=1ll*int(sqrt(n*1.0));
	for(LL i=1;i<=n;i++){
		pos(i)=(i-1)/size+1;  R[pos(i)]=i; num[pos(i)]++;
		if(!L[pos(i)]){
			L[pos(i)]=i,data++,gcd[pos(i)][1]=a[i],Xor[pos(i)][1]=a[i];
		}
		else{	
			gcd[pos(i)][num[pos(i)]]=GCD(gcd[pos(i)][num[pos(i)]-1],a[i]);
			Xor[pos(i)][num[pos(i)]]=Xor[pos(i)][num[pos(i)]-1]^a[i];
		}
		if(q[pos(i)].count(Xor[pos(i)][num[pos(i)]])==0)q[pos(i)][Xor[pos(i)][num[pos(i)]]]=num[pos(i)];
	}
	for(LL i=1;i<=data;i++)sum[i]=sum[i-1]+num[i];
}
void Update(LL x,LL y){
	q[pos(x)].clear(); 
	Xor[pos(x)][1]=a[L[pos(x)]]; gcd[pos(x)][1]=a[L[pos(x)]];
	q[pos(x)][Xor[pos(x)][1]]=1;
	for(LL i=L[Belong[x]]+1,cnt=2;i<=R[Belong[x]];i++,cnt++){
		Xor[pos(i)][cnt]=Xor[pos(i)][cnt-1]^a[i];
		gcd[pos(i)][cnt]=GCD(gcd[pos(i)][cnt-1],a[i]);
		if(q[pos(i)].count(Xor[pos(i)][cnt])==0)q[pos(i)][Xor[pos(i)][cnt]]=cnt;	
	}
	/*for(LL i=1;i<=data;i++){
		for(LL j=1;j<=num[i];j++){
	//		printf("<%lld  %lld> ",gcd[i][j],Xor[i][j]);	
		}	printf("\n");
	}*/
}
void Query(LL x){
	for(LL i=1;i<=num[1];i++){
		if(Xor[1][i]*gcd[1][i]==x){
			printf("%lld\n",i-1);
			return;	
		}	
	}
	LL temp1=gcd[1][num[1]],temp2=Xor[1][num[1]];
//	printf("--%lld %lld--\n",temp1,temp2);
	for(LL i=2;i<=data;i++){
		if(GCD(temp1,gcd[i][num[i]])==temp1){
			LL temp3=x/temp1^temp2;
			if(q[i].count(temp3)) {
				printf("%lld\n",sum[i-1]+q[i][temp3]-1);	
				return;
			}
		}	
		else{	
			for(LL j=1;j<=num[i];j++){
				LL data1=temp1,data2=temp2;
				data1=GCD(data1,gcd[i][j]);
				data2=data2^Xor[i][j];
			//	printf("--%lld %lld--\n",gcd[i][j],Xor[i][j]);
			//	printf("%lld %lld\n",data1,data2);
				if(data1*data2==x){
					printf("%lld\n",sum[i-1]+j-1);	
					return;
				}	
			}	
		}
		temp1=GCD(temp1,gcd[i][num[i]]); temp2=temp2^Xor[i][num[i]];
		//printf("--%lld %lld--\n",temp1,temp2);
	}
	printf("no\n");
	return;
}
int main(){
	freopen("gcdxor.in","r",stdin); freopen("gcdxor.out","w",stdout);
	scanf("%lld",&n);
	for(LL i=1;i<=n;i++)scanf("%lld",&a[i]);
	scanf("%lld",&m);
	Makeblock();
	//for(LL i=1;i<=data;i++)printf("%lld %lld %lld\n",L[i],R[i],num[i]);
	//for(LL i=1;i<=n;i++)printf("%lld ",pos);
	while( m-- ){
		char ch[15]; scanf("%s",ch);
		if(ch[0]=='M'){
			LL x,y; scanf("%lld%lld",&x,&y); x++; a[x]=y;
			Update(x,y);	
		}	
		else if(ch[0]=='Q'){
			LL x; scanf("%lld",&x); 
			Query(x);
		}
	}
	getchar(); getchar(); getchar(); 
	//while(1);
	return 0;	
}
/*
10
1353600 5821200 10752000 1670400 3729600 6844320 12544000 117600 59400 640
10
MODIFY 7 20321280
QUERY 162343680
QUERY 1832232960000
MODIFY 0 92160
QUERY 1234567
QUERY 3989856000
QUERY 833018560
MODIFY 3 8600
MODIFY 5 5306112
QUERY 148900352
*/
/*
80 735600
80 25314672
40 774520

--240 16624400--
--80 735600--
--80 20786544--
--40 20825464--
*/
/*
--240 16624400--
--12544000 12544000--
80 735600
--250880 25787392--
80 25314672
--40 25793544--
40 774520
*/