一眼分块题……
分块,维护每个块的总的gcd和xor和
先思考我们应该怎么查询,考虑到gcd是一个神奇的东西,因为它最多变化logX次
于是我们从前往后扫描每个块,如果一个块内总的gcd是当前扫描的前缀gcd的倍数
那么,也就意味着这个块里的每个位置所对应的前缀的gcd都等于当前gcd
因此,我们设当前xor和为nowxor,gcd为nowgcd,partxor为块内某个块前缀xor和
nowxor xor partxor*nowgcd=x 即 nowxor xor (x/nowgcd)=partxor
这时候只要查询块内是否存在某个块前缀xor和为nowxor xor (x/nowgcd)即可,这我们可以用hash解决
如果不是倍数关系,那么我们直接暴力这个块即可,这样的暴力一定不会超过logX次
至于修改,我们直接暴力重构对应块即可
1 const mo=124367; 2 type node=record 3 po,num,next:longint; 4 end; 5 6 var e:array[0..6010010] of node; 7 p:array[0..320,0..mo] of longint; 8 a,g,b,be:array[0..100010] of longint; 9 size,t,len,i,j,n,m,x,y:longint; 10 z:int64; 11 ch:char; 12 s:string; 13 14 function gcd(a,b:longint):longint; 15 begin 16 if b=0 then exit(a) 17 else exit(gcd(b,a mod b)); 18 end; 19 20 function min(a,b:longint):longint; 21 begin 22 if a>b then exit(b) else exit(a); 23 end; 24 25 procedure work(x,y,z:longint); 26 var i,j:longint; 27 begin 28 i:=p[x,y mod mo]; 29 while i<>0 do 30 begin 31 j:=e[i].po; 32 if e[i].po=y then 33 begin 34 e[i].num:=min(e[i].num,z); 35 exit; 36 end; 37 i:=e[i].next; 38 end; 39 inc(len); 40 e[len].po:=y; 41 e[len].num:=z; 42 e[len].next:=p[x,y mod mo]; 43 p[x,y mod mo]:=len; 44 end; 45 46 procedure del(x,y,z:longint); 47 var i,j:longint; 48 begin 49 i:=p[x,y mod mo]; 50 while i<>0 do 51 begin 52 j:=e[i].po; 53 if e[i].po=y then 54 begin 55 if e[i].num=z then e[i].num:=n+1; 56 exit; 57 end; 58 i:=e[i].next; 59 end; 60 end; 61 62 function get(x,y:longint):longint; 63 var i,j:longint; 64 begin 65 i:=p[x,y mod mo]; 66 while i<>0 do 67 begin 68 j:=e[i].po; 69 if j=y then exit(e[i].num); 70 i:=e[i].next; 71 end; 72 exit(n+1); 73 end; 74 75 function ask(x:int64):longint; 76 var tg,tx,i,j,r,p:longint; 77 begin 78 tg:=0; tx:=0; 79 for i:=1 to size do 80 begin 81 tg:=gcd(tg,a[i]); 82 tx:=tx xor a[i]; 83 if int64(tg)*int64(tx)=x then exit(i); 84 if x div int64(tg)>1 shl 30 then exit(-1); 85 end; 86 for i:=2 to t do 87 begin 88 if x div int64(tg)>1 shl 30 then exit(-1); 89 if i=t then r:=n else r:=i*size; 90 if g[r] mod tg=0 then 91 begin 92 if x mod tg=0 then 93 begin 94 p:=get(i,tx xor (x div int64(tg))); 95 if p<=n then exit(p); 96 end; 97 tx:=tx xor b[r]; 98 end 99 else begin 100 for j:=(i-1)*size+1 to r do 101 begin 102 tg:=gcd(tg,a[j]); 103 tx:=tx xor a[j]; 104 if int64(tg)*int64(tx)=x then exit(j); 105 if x div int64(tg)>1 shl 30 then exit(-1); 106 end; 107 end; 108 end; 109 exit(-1); 110 end; 111 112 begin 113 readln(n); 114 size:=trunc(sqrt(n)); 115 for i:=1 to n do 116 begin 117 read(a[i]); 118 be[i]:=(i-1) div size+1; 119 end; 120 t:=n div size; 121 if n mod size<>0 then inc(t); 122 for i:=1 to n do 123 begin 124 if i mod size=1 then 125 begin 126 g[i]:=a[i]; 127 b[i]:=a[i]; 128 end 129 else begin 130 b[i]:=b[i-1] xor a[i]; 131 g[i]:=gcd(g[i-1],a[i]); 132 end; 133 work(be[i],b[i],i); 134 end; 135 readln(m); 136 for i:=1 to m do 137 begin 138 s:=''; 139 read(ch); 140 while ch<>' ' do 141 begin 142 s:=s+ch; 143 read(ch); 144 end; 145 if s[1]='M' then 146 begin 147 readln(x,y); 148 inc(x); 149 a[x]:=y; 150 for j:=x to min(size*be[x],n) do 151 begin 152 del(be[x],b[j],j); 153 if j mod size=1 then 154 begin 155 b[j]:=a[j]; 156 g[j]:=a[j]; 157 end 158 else begin 159 b[j]:=b[j-1] xor a[j]; 160 g[j]:=g[j-1] xor a[j]; 161 end; 162 work(be[x],b[j],j); 163 end; 164 end 165 else begin 166 readln(z); 167 x:=ask(z); 168 if x=-1 then writeln('no') else writeln(x-1); 169 end; 170 end; 171 end.