对于 100% 的数据,n <= 100000,q <= 10000,a_i <= 10^9 (0 <= i < n),QUERY x 中的 x <= 10^18,MODIFY id x 中的 0 <= id < n,1 <= x <= 10^9.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=100010;
typedef long long ll;
int n,m,B,gn;
int tag[1000],v[maxn],s[maxn],sp[maxn],g[100],gp[100],bg[1000];
char str[20];
inline ll rd()
{
ll ret=0,f=1; char gc=getchar();
while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘)f=-f; gc=getchar();}
while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+gc-‘0‘,gc=getchar();
return ret*f;
}
int gcd(int a,int b)
{
return !b?a:gcd(b,a%b);
}
inline bool eql(ll a,ll b)
{
return (a==b)||((a)&&(b%a==0));
}
bool cmp(const int &a,const int &b)
{
return (s[a]==s[b])?(a<b):(s[a]<s[b]);
}
void getnxt()
{
int a=gp[gn]+1,c=a/B,i,j;
gn++,g[gn]=gcd(g[gn-1],v[a]);
for(j=a;j<c*B+B&&j<n;j++) if(!eql(g[gn],v[j])) {gp[gn]=j-1; return ;}
if(j==n) {gp[gn]=n-1; return ;}
for(i=c+1;i*B<n;i++) if(!eql(g[gn],bg[i])) break;
if(i*B>=n) {gp[gn]=n-1; return ;}
for(j=i*B;j<i*B+B&&j<n;j++) if(!eql(g[gn],v[j])) {gp[gn]=j-1; return ;}
gp[gn]=n-1; return ;
}
bool query(int x,ll val)
{
if(!eql(g[x],val)) return 0;
val=(!g[x])?val:val/g[x];
int a=gp[x-1]+1,b=gp[x],c=a/B,d=b/B,j;
if(c==d)
{
for(j=a;j<=b;j++) if((s[j]^tag[c])==val) {printf("%d\n",j); return 1;}
return 0;
}
for(j=a;j<c*B+B;j++) if((s[j]^tag[c])==val) {printf("%d\n",j); return 1;}
for(j=c+1;j<d;j++)
{
int l=j*B,r=j*B+B,mid;
while(l<r)
{
mid=(l+r)>>1;
if(s[sp[mid]]>=(val^tag[j])) r=mid;
else l=mid+1;
}
if(r<j*B+B&&s[sp[r]]==(val^tag[j])) {printf("%d\n",sp[r]); return 1;}
}
for(j=d*B;j<=b;j++) if((s[j]^tag[d])==val) {printf("%d\n",j); return 1;}
return 0;
}
int main()
{
n=rd(),B=int(sqrt(double(n)));
int i,j,a,c;
ll b,d;
for(i=0;i<n;i++) v[i]=rd();
gp[0]=-1,g[gn=1]=v[0];
for(i=0;i<n;i++)
{
if(i%B==0) tag[i/B+1]=tag[i/B],s[i]=v[i];
else s[i]=s[i-1]^v[i];
tag[i/B+1]^=v[i],bg[i/B]=gcd(v[i],bg[i/B]),sp[i]=i;
if(!eql(g[gn],v[i])) g[gn+1]=gcd(v[i],g[gn]),gp[gn]=i-1,gn++;
}
gp[gn]=n-1;
for(i=0;i<n;i+=B) sort(sp+i,sp+min(i+B,n),cmp);
m=rd();
for(i=1;i<=m;i++)
{
scanf("%s",str);
if(str[0]==‘M‘)
{
a=rd(),b=rd(),c=a/B,d=v[a],v[a]=b,bg[c]=0;
for(j=c*B;j<min(c*B+B,n);j++) s[j]=(j==c*B)?v[j]:s[j-1]^v[j],sp[j]=j,bg[c]=gcd(bg[c],v[j]);
sort(sp+c*B,sp+min(c*B+B,n),cmp);
for(j=c+1;j*B<n;j++) tag[j]^=(b^d);
gn=0;
while(gp[gn]<n-1) getnxt();
}
else
{
b=rd();
for(j=1;j<=gn&&!query(j,b);j++);
if(j==gn+1) printf("no\n");
}
}
return 0;
}