线段树求条
查看原帖
线段树求条
964089
run_away楼主2024/7/30 18:36

rt,就是使用线段树维护区间和和区间乘积最小,但是tle on #20

https://www.luogu.com.cn/record/169517448

#include<bits/stdc++.h>
typedef long ll;
using namespace std;
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}ll top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');}
const ll mod=1e9+7,maxn=1e5+5,maxt=505;
ll n,m,a[maxn],b[maxn];
struct node{
    int l,r;
    ll mn,sum;
}t[maxn<<2];
inline void pushup(int x){
    t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
    t[x].mn=min(t[x<<1].mn,t[x<<1|1].mn);
}
inline void build(int x,int l,int r){
    t[x].l=l,t[x].r=r;
    if(l==r){
        t[x].mn=a[l]*b[l];
        t[x].sum=a[l]+b[l];
        return;
    }int mid=(t[x].l+t[x].r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    pushup(x);
}
inline void update(int x,int pos,ll k1,ll k2){
    if(t[x].l==t[x].r){
        t[x].sum=k1+k2;
        t[x].mn=k1*k2;
        a[pos]=k1,b[pos]=k2;
        return;
    }int mid=(t[x].l+t[x].r)>>1;
    if(pos<=mid)update(x<<1,pos,k1,k2);
    else update(x<<1|1,pos,k1,k2);
    pushup(x);
}
inline void add(int x,int l,int r,ll lim,ll k){
    if(t[x].mn>lim)return;
    if(t[x].l==t[x].r){
        a[t[x].l]+=k,b[t[x].l]+=k;
        t[x].mn=a[t[x].l]*b[t[x].l],t[x].sum+=k*2;
        return;
    }int mid=(t[x].l+t[x].r)>>1;
    if(l<=mid)add(x<<1,l,r,lim,k);
    if(r>mid)add(x<<1|1,l,r,lim,k);
    pushup(x);
}
inline ll query(int x,int l,int r){
    if(l<=t[x].l&&t[x].r<=r)return t[x].sum;
    ll ans=0;int mid=(t[x].l+t[x].r)>>1;
    if(l<=mid)ans+=query(x<<1,l,r);
    if(r>mid)ans+=query(x<<1|1,l,r);
    return ans;
}
signed main(){
    n=read(),m=read();
    for(ll i=1;i<=n;++i)a[i]=read();
    for(ll i=1;i<=n;++i)b[i]=read();
    build(1,1,n);
    while(m--){
        int op=read();
        if(op==1){
            int l=read(),r=read(),lim=read(),k=read();
            if(!lim)continue;
            add(1,l,r,lim,k);
        }
        else if(op==2){
            int pos=read(),k1=read(),k2=read();
            update(1,pos,k1,k2);
        }
        else{
            int l=read(),r=read();
            write(query(1,l,r));
        }
    }
    return 0;
}
2024/7/30 18:36
加载中...