bzoj 4028 [HEOI2015]公约数数列

g[i]=gcd(a[l],a[l+1],a[i]),x[i]=xor(a[l],a[l+1],a[i])$g[i]=gcd(a[l],a[l+1],…a[i]), x[i]=xor(a[l],a[l+1],…a[i])$

(要查找的xor$xor$)=(m)(xor)/(gcd)$)=(m)*(这一块前面的xor和)/(这一块前面的gcd)$

O(Qnlog2)$O(Q*\sqrt{n}*log^{2})$的代码：

#include<bits/stdc++.h>
#define N 100010
#define LL long long
using namespace std;
template<typename T>void read(T&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
struct Q{
int id;LL v;
bool operator<(const Q&a)const{
if(v!=a.v)return v<a.v;
else return id<a.id;
}
}s[N];
LL gcd(LL x,LL y){
return y==0?x:gcd(y,x%y);
}
int l[N],r[N],P,bel[N],tot,n,m;
LL x[N],g[N],a[N];
char op[55];
int find(int L,int R,LL v){
int l=L,r=R;
while(l^r){
int mid=l+r>>1;
if(s[mid].v<v)l=mid+1;
else r=mid;
}
return s[l].v==v?s[l].id:-1;
}
void rebuild(int ps){
g[l[ps]]=x[l[ps]]=a[l[ps]];s[l[ps]]=(Q){l[ps],x[l[ps]]};
for(int i=l[ps]+1;i<=r[ps];i++){
x[i]=x[i-1]^a[i];g[i]=gcd(a[i],g[i-1]);
s[i]=(Q){i,x[i]};
}
sort(s+l[ps],s+r[ps]+1);
}
int main(){
for(int i=1;i<=n;i++){
bel[i]=(i-1)/P+1;r[bel[i]]=i;
if(bel[i]>tot)tot++,l[bel[i]]=i;
}
r[bel[n]]=n;
for(int i=1;i<=tot;i++)rebuild(i);
for(;m--;){
scanf("%s",op+1);
if(op[1]=='M'){
a[++x]=y;rebuild(bel[x]);
}
else{
LL m,_x=0,_g=a[1];bool f=0;
for(int i=1;i<=tot&&!f;i++){
if(gcd(_g,g[r[i]])==_g){
if(!(m%_g)){
int xx=find(l[i],r[i],(m/_g)^_x);
if(~xx)printf("%d\n",xx-1),f=1;
}
_x^=x[r[i]],_g=gcd(_g,g[r[i]]);
}
else{
for(int j=l[i];j<=r[i];j++){
_g=gcd(_g,a[j]);
_x=_x^a[j];
if(_g*_x==m){
printf("%d\n",j-1),f=1;
break;
}
}
}
}
if(!f)puts("no");
}
}
}