求调,只A第一点,线段树不差分做法

P1253 扶苏的问题

Herbie_ZHB @ 2024-02-07 19:28:39

#include<bits/stdc++.h>//9pts未知错误; 
using namespace std;
#define maxn 100005
int n,m,a[maxn];
typedef long long ll;
ll w[maxn*4],x[maxn*4],y[maxn*4];
void pushup(int u){
    w[u]=w[u*2]+w[u*2+1]; 
}
void build(int u,int L,int R){
    if(L==R){
        w[u]=a[L];
        return ;
    }
    int M=(L+R)>>1;
    build(u*2,L,M);
    build(u*2+1,M+1,R);
    pushup(u);
}
bool InRange(int L,int R,int l,int r){
    return l<=L&&r>=R;
}
bool OutofRange(int L,int R,int l,int r){
    return l>R||r<L;
}
ll S(ll k,ll d,ll len){
    return (k+k+d*(len-1))*len/2;
}
void maketag(int u,ll len,ll add_x,ll add_y){//
    x[u]+=add_x;y[u]+=add_y;
    //if(u==7)cout<<w[7]<<endl;
    w[u]+=S(add_x,add_y,len);
}
void pushdown(int u,int L,int R,ll add_x,ll add_y){//
    ll M=(L+R)>>1;
    maketag(u*2,M-L+1,add_x,add_y);
    ll aa=add_x;
    aa=aa+(M-L+1)*add_y;
    maketag(u*2+1,R-M,aa,add_y);
    x[u]-=add_x;
    y[u]-=add_y;
}
void update(int u,int L,int R,int l,int r,ll add_x,ll add_y){//
    if(InRange(L,R,l,r)){
        maketag(u,R-L+1,add_x,add_y);
    }else if(!OutofRange(L,R,l,r)){
        int M=(L+R)>>1;
        pushdown(u,L,R,x[u],y[u]);
        update(u*2,L,M,l,r,add_x,add_y);
        if(l<=M)add_x+=(M-l+1)*add_y; 
        update(u*2+1,M+1,R,l,r,add_x,add_y);
        pushup(u);
    }
}
ll query(int u,int L,int R,int p){   //
    if(L==R&&L==p){
        return w[u];
    }else if(p>=L&&p<=R){
        int M=(L+R)/2;
        pushdown(u,L,R,x[u],y[u]);
        if(p<=M){
            return query(u*2,L,M,p);
        }else return query(u*2+1,M+1,R,p);
    }
}
int main(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt,l,r,p;
        ll k,d;
        scanf("%d",&opt);
        if(opt==1){
            scanf("%d%d%lld%lld",&l,&r,&k,&d);
            update(1,1,n,l,r,k,d);
        }else if(opt==2){
            scanf("%d",&p);
            printf("%lld\n",query(1,1,n,p));
            //for(int i=1;i<=4*n;i++)cout<<w[i]<<' ';
            //cout<<endl; 
        }
    }
    return 0; 
}
/*
5 2
1 2 3 4 5
1 2 5 1 2
2 5
*/ 

by 天野星河 @ 2024-02-13 21:46:47

你说得对,但是题目有三种操作


by Herbie_ZHB @ 2024-04-03 13:04:43

好像知道了


|