线段树1

//单点修改查询
//http://ybt.ssoier.cn:8088/problem_show.php?pid=1549
//https://www.luogu.com.cn/problem/P1198
//用一维数组来存,当作完全二叉树来存
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
long long int m,p,n,last,t;
char op;
struct node
{
    int l,r,v;
}tr[N*4];
void pushup(int u)//更新每个区间的最大值
{
    tr[u].v=max(tr[u*2].v,tr[2*u+1].v);
}
void build(int u,int l,int r)//建立线段树
{
    tr[u]={l,r};
    if(l==r) return;
    int mid=l+r>>1;
    build(2*u,l,mid),build(2*u+1,mid+1,r);//向左建立,向右建立
}
int query(int u,int l,int r)//查询
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u].v;
    int mid=tr[u].l+tr[u].r>>1,v=0;
    if(l<=mid) v=query(2*u,l,r);
    if(r>mid) v=max(v,query(2*u+1,l,r));
    return v;
}
int modify(int u,int x,int v)//修改
{
    if(tr[u].l==x&&tr[u].r==x) tr[u].v=v;
    else{
        int mid=tr[u].l+tr[u].r>>1;
        if(x<=mid) modify(2*u,x,v);
        else modify(2*u+1,x,v);
        pushup(u);
    }
}
int main()
{
    cin>>m>>p;
    build(1,1,m);
    while(m--){
        cin>>op>>t;
        if(op=='Q'){
            last=query(1,n-t+1,n);
            cout<<last<<endl;
        }
        else{
            modify(1,n+1,(last+t)%p);
            n++;
        }
    }
    return 0;
}

 

// //区间最大字段和
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int n,m,x,y,k,a[N];
struct node{
    int l,r,all,lmax,rmax,sum;
}tr[N*4];
void pushup(node &w,node &l,node &r)
{
    w.sum=l.sum+r.sum;
    w.lmax=max(l.lmax,l.sum+r.lmax),w.rmax=max(r.sum+l.rmax,r.rmax);
    w.all=max(max(l.all,r.all),l.rmax+r.lmax);
}
void pushup(int u)
{
    pushup(tr[u],tr[2*u],tr[2*u+1]);
}
void build(int u,int l,int r)
{
    if(l==r) tr[u]={l,r,a[l],a[l],a[l],a[l]};
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(2*u,l,mid),build(2*u+1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int x,int v)
{
    if(tr[u].l==x&&tr[u].r==x) tr[u]={x,x,v,v,v,v};
    else{
        int mid=tr[u].l+tr[u].r>>1;
        if(x<=mid) modify(2*u,x,v);
        else modify(2*u+1,x,v);
        pushup(u);
    }
}
node query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
    int mid=tr[u].l+tr[u].r>>1;
    if(r<=mid) return query(2*u,l,r);
    else if(l>mid) return query(2*u+1,l,r);
    else{
        auto left=query(2*u,l,r),right=query(2*u+1,l,r);
        node res;
        pushup(res,left,right);
        return res;
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    while(m--){
        cin>>k>>x>>y;
        if(k==1){
            if(x>y) swap(x,y);
            cout<<query(1,x,y).all<<endl;
        }
        else modify(1,x,y);
    }
    return 0;
}

 

//区间最大公约数
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
char op;
int n,m,a[N];
struct node
{
    int l,r,sum,d;
}tr[4*N];
void pushup(node &w,node &l,node &r)
{
    w.sum=l.sum+r.sum;
    w.d=__gcd(l.d,r.d);
}
void pushup(int u)
{
    pushup(tr[u],tr[2*u],tr[2*u+1]);
}
void build(int u,int l,int r)
{
    if(l==r) tr[u]={l,r,a[r]-a[r-1],a[r]-a[r-1]};
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(2*u,l,mid),build(2*u+1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int x,int v)
{
    if(tr[u].l==x&&tr[u].r==x) tr[u]={x,x,tr[u].sum+v,tr[u].sum+v};
    else{
        int mid=tr[u].l+tr[u].r>>1;
        if(x<=mid) modify(2*u,x,v);
        else modify(2*u+1,x,v);
        pushup(u);
    }
}
node query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
    int mid=tr[u].l+tr[u].r>>1;
    if(r<=mid) return query(2*u,l,r);
    else if(l>mid) return query(2*u+1,l,r);
    else{
        auto left=query(2*u,l,r),right=query(2*u+1,l,r);
        node res;
        pushup(res,left,right);
        return res;
    }
}
int main()
{
    int l,r,d;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    while(m--){
        cin>>op>>l>>r;
        if(op=='Q'){
            auto left=query(1,1,l),right=query(1,l+1,r);
            cout<<abs(__gcd(left.sum,right.d))<<endl;
        }
        else{
            cin>>d;
            modify(1,l,d);
            if(r+1<=n) modify(1,r+1,-d);
        }
    }
    return 0;
}

 

//区间修改
//线段树,懒标记

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
struct node
{
    int l,r,sum,add;
}tr[4*N];
char op;
int n,m,d,k,t,a[N],l,r;
void pushup(int u)
{
    tr[u].sum=tr[2*u].sum+tr[2*u+1].sum;
}
void pushdown(int u)
{
    auto &root=tr[u],&left=tr[2*u],&right=tr[2*u+1];
    left.add+=root.add,left.sum+=(left.r-left.l+1)*root.add;
    right.add+=root.add,right.sum+=(right.r-right.l+1)*root.add;
    root.add=0;
}
void build(int u,int l,int r)
{
    if(l==r) tr[u]={l,r,a[l],0};
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(2*u,l,mid),build(2*u+1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int l,int r,int d)
{
    if(tr[u].l>=l&&tr[u].r<=r){
        tr[u].sum+=(tr[u].r-tr[u].l+1)*d;
        tr[u].add+=d;
    }
    else{
        pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid) modify(2*u,l,r,d);
        if(r>mid) modify(2*u+1,l,r,d);
        pushup(u);
    }
}
int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1,summ=0;
    if(l<=mid) summ=query(2*u,l,r);
    if(r>mid) summ+=query(2*u+1,l,r);
    return summ;                                                                                            
}
signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    while(m--){
        cin>>op>>l>>r;
        if(op=='C') cin>>d,modify(1,l,r,d);
        else cout<<query(1,l,r)<<endl;
    }
    return 0;
}

 

//亚特兰蒂斯

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
struct segment
{
    double x,y1,y2;
    int k;
    bool operator<(const segment&w)const
    {
        return x<w.x;
    }    
}seg[N*2];
struct node
{
    int l,r,cnt;
    double len;
}tr[N*8];
vector<double>ys;
int n;
int find(int x)
{
    return lower_bound(ys.begin(),ys.end(),x)-ys.begin();
}
void pushup(int u)
{
    if(tr[u].cnt) tr[u].len=ys[tr[u].r+1]-ys[tr[u].l];
    else if(tr[u].l!=tr[u].r) tr[u].len=tr[u*2].len+tr[u*2+1].len;
    else tr[u].len=0;
}
void build(int u,int l,int r)
{
    tr[u]={l,r,0,0};
    if(l!=r){
        int mid=l+r>>1;
        build(2*u,l,mid),build(2*u+1,mid+1,r);
    }
}
void modify(int u,int l,int r,int k)
{
    if(tr[u].l>=l&&tr[u].r<=r) tr[u].cnt+=k,pushup(u);
    else{
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid) modify(2*u,l,r,k);
        if(r>mid) modify(2*u+1,l,r,k);
        pushup(u);
    }
}
signed main()
{
    cin>>n;
    for(int i=0,j=0;i<n;i++){
        double x1,x2,y1,y2;
        cin>>x1>>y1>>x2>>y2;
        seg[j++]={x1,y1,y2,1};
        seg[j++]={x2,y1,y2,-1};
        ys.push_back(y1),ys.push_back(y2);
    }
    sort(ys.begin(),ys.end());
    ys.erase(unique(ys.begin(),ys.end()),ys.end());
    build(1,0,ys.size()-2);
    sort(seg,seg+2*n);
    double res=0;
    for(int i=0;i<2*n;i++){
        if(i>0) res+=tr[1].len*(seg[i].x-seg[i-1].x);
        modify(1,find(seg[i].y1),find(seg[i].y2)-1,seg[i].k);
    }
    cout<<res<<endl;
    return 0;
}
//维护序列
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,p,m,a[N],mod,x,y,z,k;
struct node
{
    int l,r,sum,add,mul;
}tr[4*N];
void pushup(int u)
{
    tr[u].sum=(tr[2*u].sum+tr[2*u+1].sum)%mod;
}
void val(node&t,int add,int mul)
{
    t.sum=(t.sum*mul+(t.r-t.l+1)*add)%mod;
    t.mul=t.mul*mul%mod,t.add=(t.add*mul+add)%mod;
}
void pushdown(int u)
{
    val(tr[2*u],tr[u].add,tr[u].mul),val(tr[2*u+1],tr[u].add,tr[u].mul);
    tr[u].mul=1,tr[u].add=0;
}
void build(int u,int l,int r)
{
    if(l==r) tr[u]={l,r,a[r],0,1};
    else{
        tr[u]={l,r,0,0,1};
        int mid=l+r>>1;
        build(2*u,l,mid),build(2*u+1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int l,int r,int add,int mul)
{
    if(tr[u].l>=l&&tr[u].r<=r) val(tr[u],add,mul);
    else{
        pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid) modify(2*u,l,r,add,mul);
        if(r>mid) modify(2*u+1,l,r,add,mul);
        pushup(u);
    }
}
int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1,res=0;
    if(l<=mid) res=query(2*u,l,r)%mod;
    if(r>mid) res=(res+query(2*u+1,l,r))%mod;
    return res;
}
signed main()
{
    cin>>n>>p;mod=p;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    cin>>m;
    while(m--){
        cin>>z>>x>>y;
        if(z==1) cin>>k,modify(1,x,y,0,k);
        else if(z==2) cin>>k,modify(1,x,y,k,1);
        else cout<<query(1,x,y)%mod<<endl;
    }
    return 0;
}

 

posted @ 2023-07-22 11:46  o-Sakurajimamai-o  阅读(17)  评论(0)    收藏  举报
-- --