• hdu5306 Gorgeous Sequence


    hdu5306 Gorgeous Sequence

    题目大意

    ​ 给你一个序列,维护区间和,区间chkmin和区间最大值

    数据范围

    数据组数T,序列长度n,操作次数m

    $T = 100,\sum n \leqslant 1000000 ,\sum m \leqslant 1000000 $

    这是一道吉司机线段树的裸题,直接维护区间最大值,次大值,最大值个数,区间和就行了。

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
    #define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
    typedef long long ll;
    inline int read(){
    	int x;
    	char c;
    	int f=1;
    	while((c=getchar())!='-' && (c<'0' || c>'9'));
    	if(c=='-') c=getchar(),f=-1;
    	x=c^'0';
    	while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
    	return x*f;
    }
    inline ll readll(){
    	ll x;
    	char c;
    	ll f=1;
    	while((c=getchar())!='-' && (c<'0' || c>'9'));
    	if(c=='-') c=getchar(),f=-1;
    	x=c^'0';
    	while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
    	return x*f;
    }
    inline bool chkmax(int &x,int y){return (y>x)?(x=y,1):0;}
    inline bool chkmin(int &x,int y){return (y<x)?(x=y,1):0;}
    const int maxn=1e6+10;
    struct Segment_tree{
    	int Max[maxn<<2],Sec[maxn<<2],tot[maxn<<2],tag[maxn<<2];
    	ll sum[maxn<<2];
    	void push_up(int x){
    		sum[x]=sum[x<<1]+sum[x<<1|1];
    		Max[x]=Max[x<<1],tot[x]=tot[x<<1],Sec[x]=max(Sec[x<<1],Sec[x<<1|1]);
    		if(chkmax(Max[x],Max[x<<1|1])) tot[x]=tot[x<<1|1],chkmax(Sec[x],Max[x<<1]);
    		else if(Max[x]==Max[x<<1|1]) tot[x]+=tot[x<<1|1];
    		else chkmax(Sec[x],Max[x<<1|1]);
    	}
    	void change(int x,int v){
    		if(Max[x]<=v) return;
    		sum[x]-=1ll*(Max[x]-v)*tot[x];
    		Max[x]=tag[x]=v;
    	}
    	void push_down(int x){
    		if(tag[x]==-1) return;
    		change(x<<1,tag[x]);
    		change(x<<1|1,tag[x]);
    		tag[x]=-1;
    	}
    	void build_tree(int x,int L,int R){
    		tag[x]=-1;
    		if(L==R){
    			Max[x]=read();tot[x]=1;
    			Sec[x]=0;sum[x]=Max[x];
    			return;
    		}
    		int Mid=(L+R)>>1;
    		build_tree(x<<1,L,Mid);
    		build_tree(x<<1|1,Mid+1,R);
    		push_up(x);
    	}
    	void update(int x,int L,int R,int ql,int qr,int v){
    		if(Max[x]<=v) return;
    		if(ql<=L && R<=qr && Sec[x]<v){
    			change(x,v);
    			return;
    		}
    		int Mid=(L+R)>>1;
    		push_down(x);
    		if(ql<=Mid) update(x<<1,L,Mid,ql,qr,v);
    		if(qr>Mid) update(x<<1|1,Mid+1,R,ql,qr,v);
    		push_up(x);
    	}
    	int query_Max(int x,int L,int R,int ql,int qr){
    		if(ql<=L && R<=qr) return Max[x];
    		push_down(x);
    		int Mid=(L+R)>>1,res=0;
    		if(ql<=Mid) res=query_Max(x<<1,L,Mid,ql,qr);
    		if(qr>Mid) chkmax(res,query_Max(x<<1|1,Mid+1,R,ql,qr));
    		push_up(x);
    		return res;
    	}
    	ll query_sum(int x,int L,int R,int ql,int qr){
    		if(ql<=L && R<=qr) return sum[x];
    		push_down(x);
    		int Mid=(L+R)>>1;
    		ll res=0;
    		if(ql<=Mid) res=query_sum(x<<1,L,Mid,ql,qr);
    		if(qr>Mid) res+=query_sum(x<<1|1,Mid+1,R,ql,qr);
    		push_up(x);
    		return res;
    	}
    }Seg;
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("segment.in","r",stdin);
    	freopen("segment.out","w",stdout);
    #endif
    	int T=read();
    	while(T--){
    		int n=read(),m=read();
    		Seg.build_tree(1,1,n);
    		while(m--){
    			int ty=read(),l=read(),r=read();
    			if(ty==0){
    				int x=read();
    				Seg.update(1,1,n,l,r,x);
    			}
    			else if(ty==1) printf("%d\n",Seg.query_Max(1,1,n,l,r));
    			else printf("%lld\n",Seg.query_sum(1,1,n,l,r));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    pch文件
    Info.plist常见的设置
    通知机制
    UITextField
    通过代码自定义cell(cell的高度不一致)
    Cell的重用原理
    UITableViewCell的contentView
    2019备考[嵌入式系统设计师]之“接口技术(上)”
    shell输入输出重定向问题
    [无私分享]最新网盘资源搜索站点
  • 原文地址:https://www.cnblogs.com/zhou888/p/8511976.html
Copyright © 2020-2023  润新知