随笔 - 531  文章 - 0  评论 - 3  阅读 - 10215 

https://ac.nowcoder.com/acm/contest/1033/B

 

区间加,求 区间 gcd [L,R]

 

 gcd (a[x],a[x+1],.....a[y] ) = gcd (a[x],  a[x+1]-a[x], a[x+2]-a[x+1] ,..... a[y]-a[y-1] )

 

 线段树维护差分数组的gcd,而区间加变为2个单点改

 a[x] 的话要维护下差分数组的前缀和,和原来的a[x] 加起来

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std ;
 const int N =5e5+10;
  
 #define int long long
 #define k1 k<<1
 #define k2 k<<1|1
  
 struct TREE{
    int l,r,g ;
 }tr[N<<2];
 int n,a[N],df[N],c[N*2];
  
 int lowbit(int x){ return x&-x; }
 int q(int x){
    int res=0 ;
    for(;x;x-=lowbit(x)) res+=c[x];
    return res;
 }
 void add(int x,int v){
    for(;x<=n;x+=lowbit(x)) c[x]+=v;
 }
 int qry(int k,int x,int y){
    int l=tr[k].l, r=tr[k].r;
    if(x<=l&&y>=r){
        return abs(tr[k].g) ;
    }
    int md=(l+r)>>1;
    int t= 0;
    if(x<=md) t=__gcd(qry(k1,x,y),t);
    if(y>md) t=__gcd(qry(k2,x,y),t);
    return abs(t);
 }
 void build(int k,int l,int r){
    tr[k].l=l,tr[k].r=r,tr[k].g= 0 ;
    if(l==r){
        tr[k].g = df[l];
        return ;
    }
    int md=(tr[k].l+tr[k].r)>>1;
    build(k1,l,md),build(k2,md+1,r);
    tr[k].g= __gcd(tr[k1].g,tr[k2].g) ;
 }
 void cg(int k,int x,int v){
    int l=tr[k].l, r=tr[k].r;
    if(x==l&&l==r){
        tr[k].g+=v;
        return ;
    }
    int md=(l+r)>>1;
    if(x<=md) cg(k1,x,v); else cg(k2,x,v);
    tr[k].g= __gcd(tr[k1].g,tr[k2].g) ;
 }
  
 //  q(x,y)
 signed main(){
    int i,x,y,z,tes;
    cin>>n>>tes ;
    for(i=1;i<=n;i++)
        cin>>a[i],df[i]=a[i]-a[i-1];
     
    build(1,1,n) ;
    while(tes--){
        char op ;
        cin>>op>>x>>y;
        if(op=='C'){
            cin>>z;
            cg(1,x,z);
            if(y+1<=n) cg(1,y+1,-z);
            add(x,z),add(y+1,-z);
        }
        else{
            int t1= a[x]+q(x), t2= qry(1,x+1,y) ;
            cout<<__gcd(t1,t2)<<'\n';
        }
    }
 }

 

posted on   towboat  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示