bzoj4028 [HEOI2015]公约数数列
2017-04-02 13:42
357 查看
Description
设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作:1. MODIFY id x: 将 a_{id} 修改为 x.
2. QUERY x: 求最小的整数 p (0 <= p < n),使得 gcd(a_0, a_1, ..., a_p) * XOR(a_0, a_1, ..., a_p) = x. 其中 XOR(a_0, a_1, ..., a_p) 代表 a_0, a_1, ..., a_p 的异或和,gcd表示最大公约数。
Input
输入数据的第一行包含一个正整数 n.接下来一行包含 n 个正整数 a_0, a_1, ..., a_{n - 1}.
之后一行包含一个正整数 q,表示询问的个数。
之后 q 行,每行包含一个询问。格式如题目中所述。
Output
对于每个 QUERY 询问,在单独的一行中输出结果。如果不存在这样的 p,输出 no.Sample Input
101353600 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
Sample Output
60
no
2
8
8
HINT
对于 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.正解:分块。
这题太鬼畜了,完全想不到。。
首先这题正解是分块。我们分好块以后,计算出每个块的$gcd$前缀和和异或前缀和,分别用$g1[i]$和$g2[i]$表示。修改的时候我们就暴力修改整个块,并更新就行了,这里的复杂度,加上之后提到的$map$,复杂度是$O(\sqrt{n}logn)$的。
如何查询?我们记录一个$lastgcd$,表示当前访问的前一个块右端点到序列起点的$gcd$;$lastxor$类似。我们计算一下$\gcd(lastgcd,g1[R[i]])$,表示当前块最后一个端点的$gcd$前缀和。如果这个值与$lastgcd$相等,那么我们可以很快想到,这一个块内的$gcd$前缀和都相等,因为$gcd$是单调不增的。那么我们就是要找到满足$lastgcd*(g2[i] \ xor \ lastxor)=x$的i值,也就是满足$g2[i]=\frac{x}{lastgcd} \ xor \ lastxor$的值。这个我们开一个$map$统计一下$g2[i]$对应的$i$就行了,同时注意这个$map$在预处理和修改时都要更新。如果不满足这个条件呢?我们直接暴力搞整个块就行了。因为我们可以发现,$gcd$减小的时候,每次最小会除$2$,也就是说,$gcd$最多只会减小$log$次。那么我们暴力查询,是可以保证复杂度在$O(\sqrt{n}logn)$的。于是我们的总复杂度就是$O(q\sqrt{n}logn)$的。
$mdzz$这题还卡常数。。我要把$long \ long$改成$int$才能过。。
//It is made by wfj_2048~ #include <algorithm> #include <iostream> #include <complex> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define inf (1<<30) #define N (100010) #define il inline #define RG register #define ll long long #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; map<int,int>mp ; int a ,bl ,LL ,RR ,g1 ,g2 ,n,q,totb,block; char s[12]; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } il ll gll(){ RG ll x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } il int gcd(RG int a,RG int b){ return b ? gcd(b,a%b) : a; } il void work(){ n=gi(),block=sqrt(n),totb=(n-1)/block+1; for (RG int i=1;i<=n;++i){ a[i]=gi(),bl[i]=(i-1)/block+1; if (!LL[bl[i]]) LL[bl[i]]=i; RR[bl[i]]=i; } for (RG int i=1;i<=totb;++i){ RG int res1=0,res2=0; for (RG int j=LL[i];j<=RR[i];++j){ g1[j]=res1=gcd(res1,a[j]),g2[j]=res2=res2^a[j]; if (!mp[i][g2[j]]) mp[i][g2[j]]=j; } } q=gi(); while (q--){ scanf("%s",s); if (s[0]=='M'){ RG int id=gi()+1,x=gi(); a[id]=x; RG int res1=0,res2=0,b=bl[id]; mp[b].clear(); for (RG int j=LL[b];j<=RR[b];++j){ g1[j]=res1=gcd(res1,a[j]),g2[j]=res2=res2^a[j]; if (!mp[b][g2[j]]) mp[b][g2[j]]=j; } } else{ RG ll x=gll(); RG int lastgcd=0,lastxor=0,ans=0; for (RG int i=1;i<=totb;++i) if (i!=1 && gcd(lastgcd,g1[RR[i]])==lastgcd){ if (x%lastgcd){ lastgcd=gcd(lastgcd,g1[RR[i]]); lastxor^=g2[RR[i]]; continue; } RG ll k=(x/lastgcd)^lastxor; if (k<=inf){ RG int v=mp[i][k]; if (v){ ans=v; break; } } lastgcd=gcd(lastgcd,g1[RR[i]]); lastxor^=g2[RR[i]]; } else{ for (RG int j=LL[i];j<=RR[i];++j){ lastgcd=gcd(lastgcd,a[j]),lastxor^=a[j]; if ((ll)lastgcd*(ll)lastxor==x){ ans=j; break; } } } if (ans) printf("%d\n",ans-1); else puts("no"); } } return; } int main(){ File("gcd"); work(); return 0; }
相关文章推荐
- BZOJ4028 [HEOI2015]公约数数列 分块
- BZOJ4028 [HEOI2015]公约数数列
- bzoj4028: [HEOI2015]公约数数列
- BZOJ4028: [HEOI2015]公约数数列
- bzoj4028[HEOI2015]公约数数列
- 【bzoj4028】[HEOI2015]公约数数列 分块
- 【BZOJ4028】[HEOI2015]公约数数列 分块
- BZOJ 4028: [HEOI2015]公约数数列 分块
- 4028: [HEOI2015]公约数数列
- bzoj 4028: [HEOI2015]公约数数列 (分块乱搞+map)
- BZOJ 4028: [HEOI2015]公约数数列
- bzoj 4028 [HEOI2015]公约数数列
- bzoj 4028 : [HEOI2015]公约数数列
- BZOJ4028 HEOI2015公约数数列(分块)
- 【bzoj4028】【HEOI2015】公约数数列【分块暴力】
- BZOJ 4028: [HEOI2015]公约数数列 分块
- [BZOJ4028] [HEOI2015] 公约数数列 - 分块
- [BZOJ4028][HEOI2015]公约数数列(分块)
- [HEOI2015] 公约数数列
- bzoj4029[HEOI2015]定价