首页 > 其他分享 >Codeforces 438D The Child and Sequence 势能线段树

Codeforces 438D The Child and Sequence 势能线段树

时间:2023-03-01 20:24:35浏览次数:50  
标签:rt 势能 Sequence int 线段 rs Codeforces ls Child

势能线段树|

拉线段树题单时发现的这道

花神游历各国的骚操作至今让我印象深刻,原来有名字

所谓势能,大意就是原本你在高空,操作一点下降一点,势能变少一点..当你落地时,修改就没意义了

因此可以打一个落地标记:)

适用在操作次数不会很多、lazytag失效时,常见的比如开根号,区间取mod,位运算。

对于此题,当区间最大值<x时就不用修改了,维护一下最大值。

修改次数的证明不会,感性理解一下取mod下降速度也很快。

 

#include<bits/stdc++.h>
#define ls (rt<<1)
#define rs (rt<<1|1)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int a[maxn];
struct seg{
    int l,r,mx;
    ll sum;
}t[maxn<<2];
void push_up(int rt){
    t[rt].mx=max(t[ls].mx,t[rs].mx);
    t[rt].sum=t[ls].sum+t[rs].sum;
}
void build(int rt,int l,int r){
    t[rt].l=l;t[rt].r=r;
    if(l==r){
       t[rt].mx=a[l];
       t[rt].sum=1ll*a[l];
       return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);build(rs,mid+1,r);
    push_up(rt);
}
void update(int rt,int l,int r,int x){
    if(l<=t[rt].l&&t[rt].r<=r){
        // update
        if(t[rt].mx<x) return;
    }
    if(t[rt].l==t[rt].r){
       t[rt].mx%=x;
       t[rt].sum=1ll*t[rt].mx;
       return;    
    }
    if(t[ls].r>=l) update(ls,l,r,x);
    if(t[rs].l<=r) update(rs,l,r,x);
    push_up(rt);
}
void modify(int rt,int l,int r,int x){
    if(l<=t[rt].l&&t[rt].r<=r){
        // update
        t[rt].mx=x;
        t[rt].sum=x;
        return;
    }
    if(t[ls].r>=l) modify(ls,l,r,x);
    if(t[rs].l<=r) modify(rs,l,r,x);
    push_up(rt);
}
ll ask(int rt,int l,int r){
    if(l<=t[rt].l&&t[rt].r<=r){
        return t[rt].sum;//
    }
    ll ans=0;
    if(t[ls].r>=l) ans+=ask(ls,l,r);//
    if(t[rs].l<=r) ans+=ask(rs,l,r);//
    return ans;
}
int n,m;
int main(){
    //freopen("lys.in","r",stdin);
    fastio;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int op;
        cin>>op;
        if(op==1){
            int l,r;cin>>l>>r;
            cout<<ask(1,l,r)<<endl;
        }
        else if(op==2){
            int l,r,x;cin>>l>>r>>x;
            update(1,l,r,x);//对x取模 
        }
        else {
            int k,x;cin>>k>>x;
            modify(1,k,k,x);
        }    
    }
} 

 

标签:rt,势能,Sequence,int,线段,rs,Codeforces,ls,Child
From: https://www.cnblogs.com/liyishui2003/p/17169571.html

相关文章