【2019.9.2】

upd 9.2: Double Cheese Yi yesterday I forgot to keep playing again and heavy ...

Segment tree

Delay mark: "The node had been modified, but its children has not been updated."

template

Interval interval plus & multiply

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define lson (o<<1)
#define rson (o<<1|1)
const int N=100000+50,M=1e6+50,inf=0x3f3f3f3f;
int n,m,P,a[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct SegmentTree{ll add,mul,sum;}tree[N<<2];
void pup(int o){tree[o].sum=((ll)tree[lson].sum+tree[rson].sum)%P;}
void updnode1(int o,int l,int r,int k){
    tree[o].sum=(tree[o].sum+(ll)(r-l+1)*k)%P;
    tree[o].add=((ll)tree[o].add+k)%P;
}
void updnode2(int o,int l,int r,int k){
    tree[o].sum=(ll)tree[o].sum*k%P;
    tree[o].add=(ll)tree[o].add*k%P;
    tree[o].mul=(ll)tree[o].mul*k%P;
}
void pudw(int o,int l,int r){
    int mid=l+r>>1;
    if(tree[o].mul!=1) updnode2(lson,l,mid,tree[o].mul),updnode2(rson,mid+1,r,tree[o].mul),tree[o].mul=1;
    if(tree[o].add) updnode1(lson,l,mid,tree[o].add),updnode1(rson,mid+1,r,tree[o].add),tree[o].add=0;
}

void upd1(int o,int l,int r,int x,int y,int k){//区间加
    if(l>y||r<x) return;
    if(x<=l&&r<=y){updnode1(o,l,r,k);return;}
    pudw(o,l,r);
    int mid=l+r>>1;
    upd1(lson,l,mid,x,y,k),upd1(rson,mid+1,r,x,y,k);
    pup(o);
}
void upd2(int o,int l,int r,int x,int y,int k){//区间乘
    if(l>y||r<x) return;
    if(x<=l&&r<=y){updnode2(o,l,r,k);return;}
    pudw(o,l,r);
    int mid=l+r>>1;
    upd2(lson,l,mid,x,y,k),upd2(rson,mid+1,r,x,y,k);
    pup(o);
}

int query(int o,int l,int r,int x,int y){
    if(l>y||r<x) return 0;
    if(x<=l&&r<=y) return tree[o].sum;
    pudw(o,l,r);
    int mid=l+r>>1;
    int ans=0;
    ans=((ll)ans+query(lson,l,mid,x,y))%P;
    ans=((ll)ans+query(rson,mid+1,r,x,y))%P;
    return ans;
    
}
void build(int o,int l,int r){
    tree[o].add=0,tree[o].mul=1;
    if(l==r){tree[o].sum=a[l];return;}
    int mid=l+r>>1;
    build(lson,l,mid),build(rson,mid+1,r);
    pup(o);
}

int main(){
    freopen("in.txt","r",stdin);
    //freopen("xor.out","w",stdout);
    rd(n),rd(m),rd(P);
    for(int i=1;i<=n;++i) rd(a[i]);
    build(1,1,n);
    for(int i=1,opt,x,y,k;i<=m;++i){
        rd(opt),rd(x),rd(y);
        if(opt==3) printf("%d\n",query(1,1,n,x,y));
        else{
            rd(k);
            if(opt==1) upd2(1,1,n,x,y,k);
            else upd1(1,1,n,x,y,k);
        }
    }
    return 0;
}

can you answer those queries III

Seeking maximum continuous dynamic sub-segment and a single point of modification +

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
#define lson (o<<1)
#define rson (o<<1|1)
const int N=5e5+5,M=1000000+5,inf=0x3f3f3f3f;
int n,m,a[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct SegmentTree{int lmx,rmx,mxs,sum;}tree[N<<2]; 
void pup(int o){
    tree[o].sum=tree[lson].sum+tree[rson].sum;
    tree[o].lmx=Max(tree[lson].lmx,tree[lson].sum+tree[rson].lmx);
    tree[o].rmx=Max(tree[rson].rmx,tree[rson].sum+tree[lson].rmx);
    tree[o].mxs=Max(Max(tree[lson].mxs,tree[rson].mxs),tree[lson].rmx+tree[rson].lmx);
}



void mdf(int o,int l,int r,int x,int k){
    if(l==r){tree[o]=(SegmentTree){k,k,k,k};return;}
    int mid=l+r>>1;
    if(x<=mid) mdf(lson,l,mid,x,k);
    else mdf(rson,mid+1,r,x,k);
    pup(o);
}

SegmentTree query(int o,int l,int r,int x,int y){
    if(x<=l&&r<=y) return tree[o];
    int mid=l+r>>1;
    if(y<=mid) return query(lson,l,mid,x,y);
    else if(x>mid) return query(rson,mid+1,r,x,y);
    else{
        SegmentTree ls,rs,ans;
        ls=query(lson,l,mid,x,y),rs=query(rson,mid+1,r,x,y);
        ans.sum=ls.sum+rs.sum;
        ans.lmx=Max(ls.lmx,ls.sum+rs.lmx);
        ans.rmx=Max(rs.rmx,rs.sum+ls.rmx);
        ans.mxs=Max(Max(ls.mxs,rs.mxs),ls.rmx+rs.lmx);
        return ans;
    }
}
void build(int o,int l,int r){
    if(l==r){tree[o]=(SegmentTree){a[l],a[l],a[l],a[l]};return;}
    int mid=l+r>>1;
    build(lson,l,mid),build(rson,mid+1,r);
    pup(o);
}

int main(){
    freopen("in.txt","r",stdin);
//  freopen("numbers.out","w",stdout);
    rd(n),rd(m);
    for(int i=1;i<=n;++i) rd(a[i]);
    build(1,1,n);
    for(int i=1,opt,x,y;i<=m;++i){
        rd(opt),rd(x),rd(y);
        if(opt==2) mdf(1,1,n,x,y);
        else{
            if(x>y) swap(x,y);
            printf("%d\n",query(1,1,n,x,y).mxs);
        }
    }
    return 0;
}

Interval GCD

Given a series of length N A, and M instructions, each instruction may be either of the following:

1, "C lrd", represents the A [l], A [l + 1], ..., A [r] are plus d.

2, "Q lr", indicating an inquiry A [l], A [l + 1], ..., A [r] the greatest common divisor (GCD).

For each inquiry, output a integer answer.

By the \ (gcd (x, y) = gcd (x, yx) \) can be pushed into the \ (gcd (x, y, z) = gcd (x, yx, zy) \) by a mathematical induction to prove that the nature of the for any number of integers are true

Maintenance difference sequence with the segment tree is then determined gcd query \ (gcd (a [l] , ask (1,1, n, l + 1, r)) \)

== too dishes only look at the standard process to gulping over

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
#define lson (o<<1)
#define rson (o<<1|1)
const int N=5e5+5,M=1000000+5,inf=0x3f3f3f3f;
int n,m;
ll a[N],b[N],c[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

ll gcd(ll A,ll B){return B?gcd(B,A%B):A;}

struct SegmentTree{ll gcd;}tree[N<<2]; 
void pup(int o){
    tree[o].gcd=gcd(tree[lson].gcd,tree[rson].gcd);
}
void mdf(int o,int l,int r,int x,ll k){
    if(l==r){tree[o].gcd+=k;return;}
    int mid=l+r>>1;
    if(x<=mid) mdf(lson,l,mid,x,k);
    else mdf(rson,mid+1,r,x,k);
    pup(o);
}
ll query(int o,int l,int r,int x,int y){
    if(x<=l&&r<=y) return Abs(tree[o].gcd);
    int mid=l+r>>1;
    ll ans=0;
    if(x<=mid) ans=gcd(ans,query(lson,l,mid,x,y));
    if(y>mid) ans=gcd(ans,query(rson,mid+1,r,x,y));
    return Abs(ans);
}
void build(int o,int l,int r){
    if(l==r){tree[o].gcd=b[l];return;}
    int mid=l+r>>1;
    build(lson,l,mid),build(rson,mid+1,r);
    pup(o);
}

int lowbit(int x){return x&(-x);}
void add(int x,ll y){
    for(;x<=n;x+=lowbit(x)) c[x]+=y;
}
ll ask(int x){
    ll ans=0;
    for(;x;x-=lowbit(x)) ans+=c[x];
    return ans;
}

int main(){
//  freopen("in.txt","r",stdin);
//  freopen("numbers.out","w",stdout);
    rd(n),rd(m),a[0]=0;
    for(int i=1;i<=n;++i) rd(a[i]),b[i]=a[i]-a[i-1];
    build(1,1,n);
    while(m--){
        char opt[5];int x,y;ll k;
        scanf("%s",opt);rd(x),rd(y);
        if(opt[0]=='C'){
            rd(k);
            mdf(1,1,n,x,k);
            if(y<n) mdf(1,1,n,y+1,-k);
            add(x,k),add(y+1,-k);
        }
        else{
            ll nw=a[x]+ask(x),val=x<y?query(1,1,n,x+1,y):0;
            printf("%lld\n",gcd(nw,val));
        }
    }
    return 0;
}

yyb the tree line summary roar ah! https://www.cnblogs.com/cjyyb/p/8567674.html

Boring columns

Arithmetic sequence can be written as \ (a + l * k \ )

Found to be a single point of inquiry can segment tree maintenance array \ (a \) differential array \ (b \)

In the interval \ ([l, r] \ ) plus a first item of \ (K \) in steps \ (D \) of the arithmetic sequence so \ (b [l] + k \, \ b [i] + d (i \ in (l , r]) \, \ b [r + 1] - (k + (rl) * d) \)

So that is a single point of inquiry interval plus +

Segment tree

\ (QAQ \) after playing the first pass forgotten pushdown lazy to empty the mark

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rg register
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
#define Abs(x) ((x)<0?-(x):(x))
#define lson (o<<1)
#define rson (o<<1|1)
const int N=1e5+5,M=32000+5,inf=0x3f3f3f3f;
int n,m,a[N],b[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct SegmentTree{int sum,add;}tree[N<<2];
void pup(int o){tree[o].sum=tree[lson].sum+tree[rson].sum;}
void updnode(int o,int l,int r,int k){
    tree[o].sum+=(r-l+1)*k;
    tree[o].add+=k;
}
void pudw(int o,int l,int r){
    int mid=l+r>>1;
    if(tree[o].add!=0) updnode(lson,l,mid,tree[o].add),updnode(rson,mid+1,r,tree[o].add),tree[o].add=0;
}
void upd(int o,int l,int r,int x,int y,int k){
    if(l>y||r<x) return;
    if(x<=l&&r<=y){updnode(o,l,r,k);return;}
    pudw(o,l,r);
    int mid=l+r>>1;
    upd(lson,l,mid,x,y,k),upd(rson,mid+1,r,x,y,k);
    pup(o);
}
int query(int o,int l,int r,int x,int y){
    if(l>y||r<x) return 0;
    if(x<=l&&r<=y) return tree[o].sum;
    pudw(o,l,r);
    int mid=l+r>>1,ans=0;
    ans+=query(lson,l,mid,x,y)+query(rson,mid+1,r,x,y);
    return ans;
}

void build(int o,int l,int r){
    tree[o].add=0;
    if(l==r){tree[o].sum=b[l];return;}
    int mid=l+r>>1;
    build(lson,l,mid),build(rson,mid+1,r);
    pup(o);
}

int main(){
    freopen("in.txt","r",stdin);
//  freopen("numbers.out","w",stdout);
    rd(n),rd(m);a[0]=0;
    for(int i=1;i<=n;++i) rd(a[i]),b[i]=a[i]-a[i-1];
    build(1,1,n);
    for(int i=1,opt,x,y,k,d;i<=m;++i){
        rd(opt);
        if(opt==1){
            rd(x),rd(y),rd(k),rd(d);
            upd(1,1,n,x,x,k),upd(1,1,n,x+1,y,d),upd(1,1,n,y+1,y+1,-(k+(y-x)*d));
        }
        else{
            rd(x);
            printf("%d\n",query(1,1,n,1,x));
        }
    }
    return 0;
}

[SHOI2008] traffic jams

This question is how weird ==

Really amazing! Do not look at the fundamental solution to a problem not think so much detail \ (QAQ \)

Connectivity segment tree maintenance

 Come from a city to another city, a total of four kinds of programs.

  img

  If the two cities on the same line (for example, s1, s2), then:

  1. s1-->s2
  2. s1-->s3,s3-->s2
  3. s1-->s4,s4-->s2
  4. s1-->s3,s3-->s4,s4-->s2

  If the two cities not on the same line (for example, s1, s4), then:

  1. s1-->s3,s3-->s4
  2. s1-->s2,s2-->s4
  3. s1-->s3,s3-->s2,s2-->s4
  4. s1-->s4

Each node represents a \ ([l, r] \ ) matrix i.e. mid \ ((l + r) / 2 \)

U: whether the communication between the first row mid, mid + 1 two

  D: if the communication between the second row mid, mid + 1 two

  l: s1, s3 whether Unicom

  r: s2, s4 whether Unicom

  u: s1, s2 whether Unicom

  d: s3, s4 whether Unicom

  q: s1, s4 whether Unicom

  p: s3, s2 whether Unicom

For the pup in luogu dalao solution to a problem is the first to explain

QAQ really want to die

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rg register
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
#define Abs(x) ((x)<0?-(x):(x))
#define lson (o<<1)
#define rson (o<<1|1)
const int N=1e5+5,M=32000+5,inf=0x3f3f3f3f;
int n,m,a[N],b[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct SegmentTree{
    bool U,D,l,r,u,d,p,q;
}tree[N<<2];
void pup(SegmentTree &x,SegmentTree l,SegmentTree r){
    x.u=(l.u&r.u&x.U)|(l.q&x.D&r.p);
    x.d=(l.d&r.d&x.D)|(l.p&x.U&r.q);
    x.l=l.l|(l.u&x.U&r.l&x.D&l.d);
    x.r=r.r|(r.u&x.U&l.r&x.D&r.d);
    x.p=(l.d&x.D&r.p)|(l.p&x.U&r.u);
    x.q=(l.u&x.U&r.q)|(l.q&x.D&r.d);
}

void mdf1(int o,int l,int r,int c,int row,int k){
    int mid=l+r>>1;
    if(mid==c){
        if(row==1) tree[o].U=k;
        else tree[o].D=k;
        pup(tree[o],tree[lson],tree[rson]);
        return;
    }
    if(c<=mid) mdf1(lson,l,mid,c,row,k);
    else mdf1(rson,mid+1,r,c,row,k);
    pup(tree[o],tree[lson],tree[rson]);
}
void mdf2(int o,int l,int r,int c,int k){
    int mid=l+r>>1;
    if(l==r){tree[o].l=tree[o].r=tree[o].p=tree[o].q=k;return;}
    if(c<=mid) mdf2(lson,l,mid,c,k);
    else mdf2(rson,mid+1,r,c,k);
    pup(tree[o],tree[lson],tree[rson]);
}

SegmentTree query(int o,int l,int r,int x,int y){
    int mid=l+r>>1;
    if(x<=l&&r<=y) return tree[o];
    if(y<=mid) return query(lson,l,mid,x,y);
    else if(x>mid) return query(rson,mid+1,r,x,y);
    else{
        SegmentTree ans=tree[o];
        pup(ans,query(lson,l,mid,x,y),query(rson,mid+1,r,x,y));
        return ans;
    }
}
void build(int o,int l,int r){
    if(l==r){tree[o].U=tree[o].D=tree[o].u=tree[o].d=1;return;}
    int mid=l+r>>1;
    build(lson,l,mid),build(rson,mid+1,r);
    pup(tree[o],tree[lson],tree[rson]);
}

int main(){
    freopen("in.txt","r",stdin);
//  freopen("numbers.out","w",stdout);
    rd(n);
    char opt[10];
    build(1,1,n);
    while(scanf("%s",opt)&&opt[0]!='E'){
        int r1,c1,r2,c2;
        rd(r1),rd(c1),rd(r2),rd(c2);
        if(c1>c2) swap(c1,c2),swap(r1,r2);
        if(opt[0]=='O'){
            if(r1==r2) mdf1(1,1,n,c1,r1,1);
            else mdf2(1,1,n,c1,1);
        }
        else if(opt[0]=='C'){
            if(r1==r2) mdf1(1,1,n,c1,r1,0);
            else mdf2(1,1,n,c1,0);
        }
        else{
            SegmentTree l=query(1,1,n,1,c1),r=query(1,1,n,c2,n),x=query(1,1,n,c1,c2);
            bool ans=0;
            if(r1==1&&r2==1)
            ans=x.u|(l.r&x.p)|(r.l&x.q)|(l.r&x.d&r.l);
            if(r1==1&&r2==2)
            ans=x.q|(l.r&x.d)|(x.u&r.l)|(l.r&x.p&r.l);
            if(r1==2&&r2==1)
            ans=x.p|(x.d&r.l)|(l.r&x.u)|(l.r&x.q&r.l);
            if(r1==2&&r2==2)
            ans=x.d|(l.r&x.q)|(x.p&r.l)|(l.r&x.u&r.l);
            puts(ans?"Y":"N");
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/lxyyyy/p/11446227.html