• HDU5306 Gorgeous Sequence


    本题要求:

    1.区间对\(x\)取 min
    2.区间和
    3.区间 min

    只是吉司机线段树板子题。

    即我们维护\(max,smax,cnt\),最大值和次大值,最大值的个数。

    在往下过程中,当且仅当\(max > p > smax\)时进行操作。

    那么我们很容易的统计。

    #include<iostream>
    #include<cstdio>
    #define ll long long 
    #define N 1000006
    
    struct P{
    	int mx,mx2,cmx,tag;
    	ll s;
    }e[N << 2];
    
    int num[N];
    
    inline int read(){
    	int ans = 0;
    	char a = getchar();
    	while(! (a <= '9' && a >= '0')) a = getchar();
    	while(a <= '9' && a >= '0')
    	ans = (ans << 3) + (ans << 1) + (a - '0'),a = getchar();
    	return ans;
    }
    
    #define ls(x) (x << 1)
    #define rs(x) (x << 1 | 1)
    #define mid ((l + r) >> 1)
    #define root 1,1,n
    #define mx(x) e[x].mx
    #define mx2(x) e[x].mx2
    #define cnt(x) e[x].cmx
    #define t(x) e[x].tag
    #define s(x) e[x].s 
    #define INF (0x7fffffff)
    
    inline void up(int u){
    	if(mx(ls(u)) < mx(rs(u))){
    		mx(u) = mx(rs(u));
    		cnt(u) = cnt(rs(u));
    		mx2(u) = std::max(mx(ls(u)),mx2(rs(u)));
    	}else{
    		if(mx(ls(u)) > mx(rs(u))){
    			mx(u) = mx(ls(u));
    			cnt(u) = cnt(ls(u));
    			mx2(u) = std::max(mx(rs(u)),mx2(ls(u)));
    		}else{
    			mx(u) = mx(ls(u));
    			cnt(u) = cnt(ls(u)) + cnt(rs(u));
    			mx2(u) = std::max(mx2(rs(u)),mx2(ls(u)));
    		}
    	}
    	s(u) = s(ls(u)) + s(rs(u));
    }
    
    inline void build (int u,int l,int r){
    	t(u) = -1;
    	if(l == r){
    		mx(u) = num[l];
    		mx2(u) = t(u) = - 1;
    		cnt(u) = 1;
    		s(u) = num[l];  
    		return ;
    	}
    	build(ls(u),l,mid);
    	build(rs(u),mid + 1,r); 
    	up(u);
    }
    
    inline void del(int u,ll tg){
    	if(mx(u) <= tg){
    		return ;
    	}
    	s(u) += (1ll * tg - mx(u)) * cnt(u);
    	mx(u) = t(u) = tg;
    }
    
    inline void down(int u){
    	if(t(u) == -1)return ;
    	del(ls(u),t(u)),del(rs(u),t(u));
    	t(u) = -1;
    }
    
    inline void modi(int u,int l,int r,int tl,int tr,ll p){
    	if(mx(u) <= p)return ;
    	if(tl <= l && r <= tr && mx2(u) < p){
    		del(u,p);
    		return;
    	}
    	down(u);
    	if(tl <= mid)modi(ls(u),l,mid,tl,tr,p);
    	if(tr > mid)modi(rs(u),mid + 1,r,tl,tr,p);
    	up(u);
    }
    
    inline ll q(int u,int l,int r,int tl,int tr){
    	if(tl <= l && r <= tr)
    	return s(u);
    	down(u);
    	ll ans = 0;
    	if(tl <= mid)
    	ans = ans + q(ls(u),l,mid,tl,tr);
    	if(tr > mid)
    	ans = ans + q(rs(u),mid + 1,r,tl,tr);
    	return ans;
    }
    
    inline ll q2(int u,int l,int r,int tl,int tr){
    	if(tl <= l && r <= tr)
    	return mx(u);
    	down(u);
    	ll ans = 0;
    	if(tl <= mid)
    	ans = std::max(ans,q2(ls(u),l,mid,tl,tr));
    	if(tr > mid)
    	ans = std::max(ans,q2(rs(u),mid + 1,r,tl,tr));
    	return ans;
    }
    
    
    inline void solve(){
    	int n,m;
    	n = read(),m = read();
    	for(int i = 1;i <= n;++i)
    	num[i] = read();
    	build(root);
    	while(m -- ){
    		int op,l,r;
    		op = read(),l = read(),r = read();
    		if(op == 0){
    			int z;
    			z = read();
    			modi(root,l,r,z);
    		}else{
    			if(op == 2)
    			std::cout<<q(root,l,r)<<std::endl;
    			else
    			std::cout<<q2(root,l,r)<<std::endl;
    		}
    	}
    }
    
    int main(){
    	ll t;
    	scanf("%lld",&t);
    	while(t -- ){
    		solve();
    	}
    }
    
  • 相关阅读:
    从零开始学VUE3.X-常用模版语法
    从零开始学3.X-生命周期函数
    从零开始学TypeScript-readonly
    从零开始学Typescript-基础类型
    从零开始学Typescript-webpack打包
    探索 .NET Core 依赖注入的 IServiceProvider
    在.NET Core 中使用 FluentValidation 进行规则验证
    盘点大厂的那些开源项目
    探索 .NET Core 依赖注入的 IServiceCollection
    使用 Benchmark.NET 测试代码性能
  • 原文地址:https://www.cnblogs.com/dixiao/p/15104809.html
Copyright © 2020-2023  润新知