90分线段树求条

P1253 扶苏的问题

zhoukangming @ 2024-12-01 19:27:54

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct tree{
    ll l,r,maxi,mini,sumi,lazy_1=0,lazy_2=1,lazy_3;
    bool flag=0;
    tree *left=NULL,*right=NULL;
};
ll a[1145141],n,m;
tree *top;
ll read(){
    char c=getchar();
    while(c==' ' || c=='\n')c=getchar();
    if(c=='-'){
        return -read();
    }ll x=0;
    while(c!=' ' && c!='\n'){
        x=(x<<3)+(x<<1)+c-48;
        c=getchar();
    }return x;
}void paint(ll x){
    if(x<0){
        putchar('-');
        x=-x;
    }if(x>9){
        paint(x/10);
        x%=10;
    }putchar(x+48);
}
tree* build(ll l,ll r){
    tree *x=new tree;
    x->l=l;
    x->r=r;
    if(l==r){
        x->maxi=x->mini=x->sumi=a[l];
        return x;
    }x->left=build(l,(l+r)>>1);
    x->right=build(((l+r)>>1)+1,r);
    x->maxi=max(x->left->maxi,x->right->maxi);
    x->mini=min(x->left->mini,x->right->mini);
    x->sumi=x->left->sumi+x->right->sumi;
    return x;
}void add(tree *x,ll v){
    x->lazy_1+=v;
    x->maxi+=v;
    x->mini+=v;
    x->sumi+=v*(x->r-x->l+1);
}void mul(tree *x,ll v){
    x->lazy_1*=v;
    x->lazy_2*=v;
    x->maxi*=v;
    x->mini*=v;
    x->sumi*=v;
}void change(tree *x,ll v){
    x->lazy_1=0;
    x->lazy_2=0;
    x->lazy_3=v;
    x->flag=1;
    x->maxi=v;
    x->mini=v;
    x->sumi=v*(x->r-x->l+1);
}void pushdown(tree *x){
    if(x->left==NULL){
        return;
    }if(x->flag==1){
        change(x->left,x->lazy_3);
        change(x->right,x->lazy_3);
        x->flag=0;
    }if(x->lazy_2>1){
        mul(x->left,x->lazy_2);
        mul(x->right,x->lazy_2);
        x->lazy_2=1;
    }if(x->lazy_1!=0){
        add(x->left,x->lazy_1);
        add(x->right,x->lazy_1);
        x->lazy_1=0;
    }
}void date_add(tree *x,ll l,ll r,ll v){
    if(x->l>=l && x->r<=r){
        add(x,v);
        return;
    }pushdown(x);
    if(x->left->l<=r && x->left->r>=l){
        date_add(x->left,l,r,v);
    }if(x->right->l<=r && x->right->r>=l){
        date_add(x->right,l,r,v);
    }x->sumi=x->left->sumi+x->right->sumi;
    x->maxi=max(x->left->maxi,x->right->maxi);
    x->mini=min(x->left->mini,x->right->mini);
}void date_mul(tree *x,ll l,ll r,ll v){
    if(x->l>=l && x->r<=r){
        mul(x,v);
        return;
    }pushdown(x);
    if(x->left->l<=r && x->left->r>=l){
        date_mul(x->left,l,r,v);
    }if(x->right->l<=r && x->right->r>=l){
        date_mul(x->right,l,r,v);
    }x->sumi=x->left->sumi+x->right->sumi;
    x->maxi=max(x->left->maxi,x->right->maxi);
    x->mini=min(x->left->mini,x->right->mini);
}void date_change(tree *x,ll l,ll r,ll v){
    if(x->l>=l && x->r<=r){
        change(x,v);
        return;
    }pushdown(x);
    if(x->left->l<=r && x->left->r>=l){
        date_change(x->left,l,r,v);
    }if(x->right->l<=r && x->right->r>=l){
        date_change(x->right,l,r,v);
    }x->sumi=x->left->sumi+x->right->sumi;
    x->maxi=max(x->left->maxi,x->right->maxi);
    x->mini=min(x->left->mini,x->right->mini);
}ll query_max(tree *x,ll l,ll r){
    if(x->l>=l && x->r<=r){
        return x->maxi;
    }pushdown(x);
    ll maxi=-1145141919810;
    if(x->left->l<=r && x->left->r>=l){
        maxi=max(maxi,query_max(x->left,l,r));
    }if(x->right->l<=r && x->right->r>=l){
        maxi=max(maxi,query_max(x->right,l,r));
    }return maxi;
}ll query_min(tree *x,ll l,ll r){
    if(x->l>=l && x->r<=r){
        return x->mini;
    }pushdown(x);
    ll mini=1145141919810;
    if(x->left->l<=r && x->left->r>=l){
        mini=min(mini,query_min(x->left,l,r));
    }if(x->right->l<=r && x->right->r>=l){
        mini=min(mini,query_min(x->right,l,r));
    }return mini;
}ll query_sum(tree *x,ll l,ll r){
    if(x->l>=l && x->r<=r){
        return x->sumi;
    }pushdown(x);
    ll sumi=0;
    if(x->left->l<=r && x->left->r>=l){
        sumi+=query_sum(x->left,l,r);
    }if(x->right->l<=r && x->right->r>=l){
        sumi+=query_sum(x->right,l,r);
    }return sumi;
}int main(){
    n=read();
    m=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
    }top=build(1,n);
    for(int i=1;i<=m;i++){
        ll op;
        op=read();
        if(op==3){
            ll x=read(),y=read();
            paint(query_max(top,x,y));
            putchar('\n');
        }if(op==2){
            ll x=read(),y=read(),z=read();
            date_add(top,x,y,z);
        }if(op==1){
            ll x=read(),y=read(),z=read();
            date_change(top,x,y,z);
        }
    }
    return 0;
}

3TLE了,下载样例后自测没有任何问题


by ni_ju_ge @ 2024-12-01 22:09:10

@chen_zhe 来修一下数据吧


by ni_ju_ge @ 2024-12-01 22:09:47

破案了,那个数据最后一行没有换行,导致快读出错,用 std::cin 吧 @zhoukangming


by zhoukangming @ 2024-12-02 20:34:23

@ni_ju_ge666


by zhoukangming @ 2024-12-02 20:39:07

@ni_ju_ge 那,这次呢


by ni_ju_ge @ 2024-12-02 20:44:41

@zhoukangming 布什,戈门\ 评测环境不同,本地 AC \not= 线上 AC


by zhoukangming @ 2024-12-02 20:50:17

@ni_ju_ge 把原来的代码又交了一遍,就这样了


|