社区讨论

无差分线段树做法全RE求调

P1438无聊的数列参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mir9e1mr
此快照首次捕获于
2025/12/04 17:54
3 个月前
此快照最后确认于
2025/12/06 16:25
3 个月前
查看原帖
线段树不熟练*n,求调玄关
CPP
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e5+10;
int n,m,k,d,l,r,p,a[N];
char opt;
struct Q{
    bool b=false;
    int l,r,tagk,tagd,sum;
}t[N<<2];
inline void build(int l,int r,int i){
    t[i].l=l;t[i].r=r;
    if(l==r){
        t[i].sum=a[l];
        return;
    }int mid=(l+r)>>1;
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
}inline void spread(int i){
    if(t[i].b){
        t[i<<1].tagk+=t[i].tagk;
        t[i<<1].tagd+=t[i].tagd;
        t[i<<1].b=t[i<<1|1].b=true;
        t[i<<1|1].tagk+=t[i].tagk+(t[i<<1].r-t[i<<1].l+1)*t[i].tagd;
        t[i<<1|1].tagd+=t[i].tagd;
        t[i].b=false;
        t[i].tagd=t[i].tagk=0;
    }
}inline void change(int l,int r,int i,int k,int d){
    if(l<=t[i].l&&t[i].r<=r){
        t[i].b=1;
        t[i].tagk+=k+(t[i].l-l+1)*d;
        t[i].tagd+=d;
    }spread(i);
    int mid=(t[i].l+t[i].r)>>1;
    if(l<=mid) change(l,r,i<<1,k,d);
    if(r>mid) change(l,r,i<<1|1,k,d);
}inline int ask(int i,int p){
    if(t[i].l==t[i].r){
        t[i].sum+=t[i].tagk;
        t[i].tagk=t[i].tagd=0;
        return t[i].sum;
    }spread(i);
    int mid=(t[i].l+t[i].r)>>1;
    if(p<=mid) return ask(i<<1,p);
    else return ask(i<<1|1,p);
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(nullptr);cout.tie(nullptr);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    build(1,n,1);
    while(m--){
        cin>>opt;
        if(opt=='1'){
            cin>>l>>r>>k>>d;
            change(l,r,1,k,d);
        }else{
            cin>>p;
            cout<<ask(1,p)<<endl;
        }
    }
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...