給定一個長度爲N的數列A,以及M條指令 (N≤5*10^5, M<=10^5),每條指令多是如下兩種之一:
「C l r d」,表示把 A[l],A[l+1],…,A[r] 都加上 d。
「Q l r」,表示詢問 A[l],A[l+1],…,A[r] 的最大公約數(GCD)
題目描述
給定一個長度爲N的數列A,以及M條指令 (N≤5*10^5, M<=10^5),每條指令多是如下兩種之一:
「C l r d」,表示把 A[l],A[l+1],…,A[r] 都加上 d。
「Q l r」,表示詢問 A[l],A[l+1],…,A[r] 的最大公約數(GCD)輸入
第一行兩個整數N,M,第二行N個整數Ai,接下來M行每條指令的格式如題目描述所示。輸出
對於每一個詢問,輸出一個整數表示答案。樣例輸入
5 5 1 3 5 7 9 Q 1 5 C 1 5 1 Q 1 5 C 3 3 6 Q 2 4樣例輸出
1 2 4提示
N,M≤2*10^5,l<=r,數據保證任什麼時候刻序列中的數都是不超過2^62-1的正整數。c++
gcd(x,y)=gcd(x,y-x),gcd(x,y,z)=gcd(x,y-x,z-y)……對任意多個整數都成 將A數列進行查分,線段樹維護差分序列的最大公約數,每次詢問就是gcd(A[l],query(1,1,n,l+1,r); 每次修改update(1,1,n,l,d),update(1,1,n,r+1,-d) A數組也須要維護,線段樹和樹狀數組都行
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=500200; char s[10]; ll a[maxn],b[maxn],B[maxn*4],n,m,A[maxn*4]; void build (int rt,int l,int r) { if (l==r) { B[rt]=b[l]; return; } int mid=(l+r)>>1; build (rt<<1,l,mid); build (rt<<1|1,mid+1,r); B[rt]=__gcd(B[rt<<1],B[rt<<1|1]); } void update(int rt,int l,int r,int pos,ll val) { if (l==r) { B[rt]+=val; return; } int mid=(l+r)>>1; if (pos<=mid) { update(rt<<1,l,mid,pos,val); } else { update(rt<<1|1,mid+1,r,pos,val); } B[rt]=__gcd(B[rt<<1],B[rt<<1|1]); } ll query(int rt,int l,int r,int L,int R) { if (L<=l&&r<=R) { return B[rt]; } int mid=(l+r)>>1; if (R<=mid) { return query(rt<<1,l,mid,L,R); } else { if (L>mid) { return query(rt<<1|1,mid+1,r,L,R); } else { return __gcd(query(rt<<1|1,mid+1,r,L,R),query(rt<<1,l,mid,L,R)); } } } int lowbit(int x) { return x&-x; } void add(int x,ll val) { for (int i=x; i<=n; i+=lowbit(i)) { A[i]+=val; } } ll sum(int x) { ll res=0; for (int i=x; i; i-=lowbit(i)) { res+=A[i]; } return res; } int main() { scanf("%lld%lld",&n,&m); for (int i=1; i<=n; i++) { scanf("%lld",&a[i]); b[i]=a[i]-a[i-1]; add(i,b[i]); } build (1,1,n); while (m--) { ll l,r,d; scanf("%s",s); if (s[0]=='C') { scanf("%lld%lld%lld",&l,&r,&d); update(1,1,n,l,d); add(l,d); add(r+1,-d); if (r+1<=n) update(1,1,n,r+1,-d); } else { scanf("%lld%lld",&l,&r); ll ans=abs(__gcd(sum(l),query(1,1,n,l+1,r))); printf("%lld\n",ans); } } return 0; }