线段树求调(马蜂良好+悬关)

P3372 【模板】线段树 1

Zikl @ 2023-11-14 22:03:17

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int N=1e5+5;
int n,m,a[N];
int tree[N*4],lazy[N*4];
void pushup(int rt){
    tree[rt]=tree[ls(rt)]+tree[rs(rt)];
}
void build(int rt,int l,int r){
    if(l==r) tree[rt]=a[l];
    else{
        int mid=(l+r)>>1;
        build(ls(rt),l,mid);
        build(rs(rt),mid+1,r);
        pushup(rt);
    }
}
void pushdown(int rt,int l,int r){
    if(lazy[rt]){
        int mid=(l+r)>>1;
        lazy[ls(rt)]+=lazy[rt];
        lazy[rs(rt)]+=lazy[rt];
        tree[ls(rt)]+=lazy[rt]*(mid-l+1);
        tree[rs(rt)]+=lazy[rt]*(r-mid);
        lazy[rt]=0;
    }
}
void update(int rt,int l,int r,int x,int y,int k){
    if(l>=x&&r<=y){
        tree[rt]+=k*(l-r+1),lazy[rt]+=k;
        return;
    }
    int mid=(l+r)>>1;
    pushdown(rt,l,r);
    if(x<=mid) update(ls(rt),l,mid,x,y,k);
    if(y>mid)  update(rs(rt),mid+1,r,x,y,k);
    pushup(rt);
}
int query(int rt,int l,int r,int x,int y){
    if(l>=x&&r<=y) return tree[rt];
    int mid=(l+r)>>1,ans=0;
    pushdown(rt,l,r);
    if(x<=mid) ans+=query(ls(rt),l,mid,x,y);
    if(y>mid)  ans+=query(rs(rt),mid+1,r,x,y);
    return ans;
}
signed main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt=read();
        if(opt==1){
            int x=read(),y=read(),k=read();
            update(1,1,n,x,y,k);
        }
        if(opt==2){
            int x=read(),y=read();
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

这是我今天改良马蜂后的线段树

以下是之前的:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int N=100005;
int n,m,a[N];
int tree[N*4],lazy[N*4];
void maintain(int root){
    tree[root]=tree[root<<1]+tree[root<<1|1];
}
void build(int root,int l,int r){
    if(l==r) tree[root]=a[l];
    else{
        int mid=(l+r)/2;
        build(root<<1,l,mid);
        build(root<<1|1,mid+1,r);
        maintain(root);
    }
}
void pushdown(int root,int l,int r){
    if(lazy[root]){
        int mid=(l+r)/2;
        lazy[root<<1]+=lazy[root];
        lazy[root<<1|1]+=lazy[root];
        tree[root<<1]+=lazy[root]*(mid-l+1);
        tree[root<<1|1]+=lazy[root]*(r-mid);
        lazy[root]=0;
    }
}
void update(int root,int l,int r,int x,int y,int k){
    if(l>=x&&r<=y){
        lazy[root]+=k;
        tree[root]+=k*(r-l+1);
    }
    else{
        int mid=(l+r)/2;
        pushdown(root,l,r);
        if(x<=mid) update(root<<1,l,mid,x,y,k);
        if(mid+1<=y) update(root<<1|1,mid+1,r,x,y,k);
        maintain(root);
    }
}
int query(int root,int l,int r,int x,int y){
    if(l>=x&&r<=y) return tree[root];
    int mid=(l+r)/2,ans=0;
    pushdown(root,l,r);
    if(x<=mid) ans+=query(root<<1,l,mid,x,y);
    if(mid+1<=y) ans+=query(root<<1|1,mid+1,r,x,y);
    return ans; 
}
signed main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt=read();
        if(opt==1){
            int x=read(),y=read(),k=read();
            update(1,1,n,x,y,k);
        }
        if(opt==2){
            int x=read(),y=read();
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

后者AC而前者全WA,我用比较器对了114514回,还是没有找出不同,比较器


by UYHW @ 2023-11-14 22:06:28

upd里


by UYHW @ 2023-11-14 22:07:08

k*(l-r+1)


by LIUYC_C @ 2023-11-14 22:08:35

@UYHW 慢了你十多秒qwq


by UYHW @ 2023-11-14 22:08:51

qwq


by AC_love @ 2023-11-14 22:08:52

r-l+1


by Zikl @ 2023-11-14 22:30:54

@UYHW @LIUYC_C @AC_love 原来如此,谢谢,已关


|