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

势能线段树|

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

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

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

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

适用在操作次数不会很多、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);
        }    
    }
} 
复制代码

 

posted @   liyishui  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示