线段树 区间修改 最小值+最大值 最假女选手
最假女选手
题目描述
在刚刚结束的水题嘉年华的压轴节目放水大赛中,wyywyy如愿以偿的得到了最假女选手的奖项。但是作为主办人的
C_SUNSHINE为了证明wyywyy确实在放水,决定出一道基础题考察wyywyy的姿势水平。给定一个长度为 N序列,编号
从1 到 N。要求支持下面几种操作:
1.给一个区间[L,R] 加上一个数x
2.把一个区间[L,R] 里小于x 的数变成x
3.把一个区间[L,R] 里大于x 的数变成x
4.求区间[L,R] 的和
5.求区间[L,R] 的最大值
6.求区间[L,R] 的最小值
输入
第一行一个整数 N表示序列长度。
第二行N 个整数Ai 表示初始序列。
第三行一个整数M 表示操作个数。
接下来M 行,每行三或四个整数,第一个整数Tp 表示操作类型,接下来L,R,X 或L,R 表述操作数。
1<=tp<=6,N,M<=5*10^5,
|Ai|<=10^8
Tp=1时,|x|<=1000
Tp=2或3时,|x|<=10^8
输出
对于每个4,5,6类型的操作输出一行一个整数表示答案。
样例输出
2
1 2
2
2 1 2 2
4 1 2
样例输出
4
#include<bits/stdc++.h>
#define ll long long
#define a u<<1
#define b u<<1|1
using namespace std;
const int N=5e5,M=N*4;
const int inf=0x3f3f3f3f;
inline int read()
{register int s=0,w=1;register char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;
}
int le[M],ri[M],mx[M],mxs[M],mi[M],mis[M],add[M],tag1[M],tag2[M],w[N],cnt1[M],cnt2[M];
ll sum[M];
void pushup(int u)
{sum[u]=sum[a]+sum[b];if(mx[a]==mx[b]){mx[u]=mx[a];mxs[u]=max(mxs[a],mxs[b]);cnt1[u]=cnt1[a]+cnt1[b];}else if(mx[a]>mx[b]){mx[u]=mx[a];cnt1[u]=cnt1[a];mxs[u]=max(mxs[a],mx[b]);}else{mx[u]=mx[b];cnt1[u]=cnt1[b];mxs[u]=max(mxs[b],mx[a]);}if(mi[a]==mi[b]){mi[u]=mi[a];mis[u]=min(mis[a],mis[b]);cnt2[u]=cnt2[a]+cnt2[b];}else if(mi[a]<mi[b]){mi[u]=mi[a];cnt2[u]=cnt2[a];mis[u]=min(mis[a],mi[b]);}else{mi[u]=mi[b];cnt2[u]=cnt2[b];mis[u]=min(mis[b],mi[a]);}
}
void push_add(int u,int v)
{sum[u]+=(ll)(ri[u]-le[u]+1)*v;mx[u]+=v,mi[u]+=v;if(mxs[u]!=-inf) mxs[u]+=v;if(mis[u]!=inf) mis[u]+=v;if(tag1[u]!=-inf) tag1[u]+=v;if(tag2[u]!=inf) tag2[u]+=v;add[u]+=v;
}
void push_max(int u,int v)
{if(mi[u]>v) return ;sum[u]+=(ll)(v-mi[u])*cnt2[u];if(mxs[u]==mi[u]) mxs[u]==v;if(mx[u]==mi[u]) mx[u]=v;if(tag2[u]<v) tag2[u]=v;mi[u]=v,tag1[u]=v;
}
void push_min(int u,int v)
{if(mx[u]<=v) return ;sum[u]+=(ll)(v-mx[u])*cnt1[u];if(mis[u]==mx[u]) mis[u]=v;if(mi[u]==mx[u]) mi[u]=v;if(tag1[u]>v) tag1[u]=v;mx[u]=v,tag2[u]=v;
}
void pushdown(int u)
{if(add[u]){push_add(a,add[u]),push_add(b,add[u]);}if(tag1[u]!=-inf){push_max(a,tag1[u]),push_max(b,tag1[u]);}if(tag2[u]!=inf){push_min(a,tag2[u]),push_min(b,tag2[u]);}add[u]=0,tag1[u]=-inf,tag2[u]=inf;
}
void build(int u,int l,int r)
{le[u]=l,ri[u]=r,mxs[u]=-inf,mis[u]=inf;tag1[u]=-inf,tag2[u]=inf,add[u]=0;if(l==r){sum[u]=mx[u]=mi[u]=w[l];cnt1[u]=1,cnt2[u]=1;}else{int mid=l+r>>1;build(a,l,mid);build(b,mid+1,r);pushup(u);}
}
void modify_add(int u,int l,int r,int v)
{if(le[u]>=l&&ri[u]<=r){return push_add(u,v);}else{pushdown(u);int mid=le[u]+ri[u]>>1;if(mid>=l) modify_add(a,l,r,v);if(mid<r) modify_add(b,l,r,v);pushup(u);}
}
void modify_min(int u,int l,int r,int v)
{if(mx[u]<=v) return ;if(le[u]>=l&&ri[u]<=r&&mxs[u]<v) return push_min(u,v);int mid=le[u]+ri[u]>>1;pushdown(u);if(mid>=l) modify_min(a,l,r,v);if(mid<r) modify_min(b,l,r,v);pushup(u);
}
void modify_max(int u,int l,int r,int v)
{if(mi[u]>=v) return ;if(le[u]>=l&&ri[u]<=r&&mis[u]>v) return push_max(u,v);int mid=le[u]+ri[u]>>1;pushdown(u);if(mid>=l) modify_max(a,l,r,v);if(mid<r) modify_max(b,l,r,v);pushup(u);
}
ll query_sum(int u,int l,int r)
{if(le[u]>=l&&ri[u]<=r) return sum[u];pushdown(u);int mid=le[u]+ri[u]>>1;ll su=0;if(mid>=l) su+=query_sum(a,l,r);if(mid<r) su+=query_sum(b,l,r);return su;
}
int query_min(int u,int l,int r)
{if(le[u]>=l&&ri[u]<=r) return mi[u];pushdown(u);int mid=le[u]+ri[u]>>1;int su=inf;if(mid>=l) su=min(query_min(a,l,r),su);if(mid<r) su=min(su,query_min(b,l,r));return su;
}
int query_max(int u,int l,int r)
{if(le[u]>=l&&ri[u]<=r) return mx[u];pushdown(u);int mid=le[u]+ri[u]>>1;int su=-inf;if(mid>=l) su=max(query_max(a,l,r),su);if(mid<r) su=max(su,query_max(b,l,r));return su;
}
int main()
{int n,m;n=read();for(int i=1;i<=n;i++)w[i]=read();build(1,1,n);m=read();while(m--){int op,x,y,z;op=read(),x=read(),y=read();if(op<4){z=read();if(op==1) modify_add(1,x,y,z);else if(op==2) modify_max(1,x,y,z);else if(op==3) modify_min(1,x,y,z);}else{if(op==4) printf("%lld\n",query_sum(1,x,y));else if(op==5) printf("%d\n",query_max(1,x,y));else printf("%d\n",query_min(1,x,y));}}return 0;
}
具体看这里
线段树 区间修改 最小值+最大值 最假女选手相关推荐
- python:线段树区间修改 + 区间查询 模板 + 坑点总结
from functools import reduceclass SegTree:'''支持增量更新,覆盖更新,序列更新,任意RMQ操作基于二叉树实现初始化:O(1)增量更新或覆盖更新的单次操作复杂 ...
- 【模板】线段树区间修改
区间修改: 区间修改过程类似于区间询问,例如将[ul, ur]内的所有元素都加上v,则进行如下操作: 当当前区间被区间[ul, ur]所包含时, 当前的节点值加上区间长度(r - l + 1)乘以v ...
- codeforces:E2. Array and Segments (Hard version)【线段树 + 区间修改】
分析 思路很简单 遍历每个作为最大值,然后区间不包含当前最大值的都可以减掉 easy version就可以这样暴力解决 然后求出最大差值 暴力解法 import sys input = sys.std ...
- POJ 2777 Count Color (线段树区间修改 + 状态压缩)
题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时 板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...
- HDU 1698 Just a Hook (线段树区间修改+区间查询)
题目链接: 传送门 题意:Pudge对装备钩子进行若干次的强化,强化分为三种分别对应的价值是1,2,3,在经历过若干次操作后,输出钩子对应的总价值,每次强化都是对钩子进行区间修改 解题思路:在明白了题 ...
- hdu1698(线段树/区间修改/求和)
hdu1698"Just a Hook" 题意: 有一个区间s [1,n],每一节si的初始价值为1.定义操作:x y val,将区间[x,y]中的每一个小节的价值改为val.问: ...
- 1631 小鲨鱼在51nod小学(线段树区间修改+单点查询:不用下传lazy的区间修改)
题目描述: 1631 小鲨鱼在51nod小学 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务. 每一个职务都有一个起始时间A和结束时间B, ...
- tzoj3315 买火车票(线段树+区间修改+区间查询)
时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte 描述 Byteotian州铁道部决定赶上时代,为此他们引进了城市联网.假设城市联网顺次连接着n 个市从1 ...
- UVa 11992 (线段树 区间修改) Fast Matrix Operations
比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...
最新文章
- rs485协议_你知道HART和RS485协议的区别吗?
- 快速配置Windows 2003平台下实现 IIS(WEB)站点的安全(SSL加密技术!)
- Spring MVC配置静态资源的正常访问
- Jboss4集群配置之四:启动Jboss集群
- android沉浸式 字体,全面解析android沉浸式状态栏
- iTerm2 隐藏用户名和主机名
- leetcode:剑指offer----数组中重复的数字
- 漫步最优化十二——局部极小与极大的充分必要条件(下)
- autojs命令代码大全_各个主流品牌手机的命令代码大全,安卓工程模式的指令大全!...
- 微服务升级_SpringCloud Alibaba工作笔记0021---Nacos之DataId配置
- 说说Asp.net 身份验证、授权
- 1.1 Mysql安装包 windows
- VC2012 小助手的破解
- 银行学生助学贷款管理系统免费PPT模板
- igs游戏linux模拟器,IGS经典游戏FBAS模拟器典藏版
- 无人机成测绘界“全能战士”
- Alert Log中“Fatal NI connect error 12170”错误
- 2020再见,2021你好之年度总结
- java实现在线预览word,excel,ppt文档
- 《机器学习技法》第13课笔记 深度学习