线段树练习5(codevs 4927)
有n个数和5种操作
add a b c:把区间[a,b]内的所有数都增加c
set a b c:把区间[a,b]内的所有数都设为c
sum a b:查询区间[a,b]的区间和
max a b:查询区间[a,b]的最大值
min a b:查询区间[a,b]的最小值
第一行两个整数n,m,第二行n个整数表示这n个数的初始值
接下来m行操作,同题目描述
对于所有的sum、max、min询问,一行输出一个答案
10 6
3 9 2 8 1 7 5 0 4 6
add 4 9 4
set 2 6 2
add 3 8 2
sum 2 10
max 1 7
min 3 6
49
11
4
10%:1<n,m<=10
30%:1<n,m<=10000
100%:1<n,m<=100000
保证中间结果在long long(C/C++)、int64(pascal)范围内
/*
线段树的裸题,用分块写略麻烦。
对于每个块维护两个标记,添加标记和修改标记,修改的时候对于完整的块只修改标记,对于不完整的块,暴力修改,查询也是一样。
*/
#include<cstdio>
#include<iostream>
#include<cmath>
#define N 100010
#define inf 1000000000
#define lon long long
using namespace std;
int val[N],mx[N],mn[N],tag1[N],tag2[N],bl[N],n,m,len;lon sum[N]; void pushdown(int k){
if(tag2[k]!=-){
for(int i=(k-)*len+;i<=min(k*len,n);i++)
val[i]=tag2[k];
tag1[k]=;tag2[k]=-;
}
if(tag1[k]){
for(int i=(k-)*len+;i<=min(k*len,n);i++)
val[i]+=tag1[k];
tag1[k]=;
}
} void modify(int x,int y,int z){
//下放x不完整区间
int k=bl[x];pushdown(k);
for(int i=x;i<=min(k*len,y);i++) val[i]+=z;
sum[k]=;mx[k]=-inf;mn[k]=inf;
for(int i=(k-)*len+;i<=min(k*len,n);i++)
sum[k]+=(lon)val[i],mx[k]=max(mx[k],val[i]),mn[k]=min(mn[k],val[i]);
//下放完整区间
for(int i=bl[x]+;i<bl[y];i++){
if(tag2[i]!=-) tag2[i]+=z;
else tag1[i]+=z;
sum[i]+=(lon)z*(lon)len;mx[i]+=z;mn[i]+=z;
}
//下放y不完整区间
if(bl[x]==bl[y]) return;
k=bl[y];pushdown(k);
for(int i=(k-)*len+;i<=y;i++) val[i]+=z;
sum[k]=;mx[k]=-inf;mn[k]=inf;
for(int i=(k-)*len+;i<=min(k*len,n);i++)
sum[k]+=(lon)val[i],mx[k]=max(mx[k],val[i]),mn[k]=min(mn[k],val[i]);
} void change(int x,int y,int z){
//下放x不完整区间
int k=bl[x];pushdown(k);
for(int i=x;i<=min(k*len,y);i++) val[i]=z;
sum[k]=;mx[k]=-inf;mn[k]=inf;
for(int i=(k-)*len+;i<=min(k*len,n);i++)
sum[k]+=(lon)val[i],mx[k]=max(mx[k],val[i]),mn[k]=min(mn[k],val[i]);
//下方完整区间
for(int i=bl[x]+;i<bl[y];i++)
tag2[i]=mx[i]=mn[i]=z,sum[i]=(lon)z*(lon)len,tag1[i]=;
//下放y不完整区间
if(bl[x]==bl[y]) return;
k=bl[y];pushdown(k);
for(int i=(k-)*len+;i<=y;i++) val[i]=z;
sum[k]=;mx[k]=-inf;mn[k]=inf;
for(int i=(k-)*len+;i<=min(k*len,n);i++)
sum[k]+=(lon)val[i],mx[k]=max(mx[k],val[i]),mn[k]=min(mn[k],val[i]);
} lon querysum(int x,int y){
lon tot=;int k=bl[x];
pushdown(k);
for(int i=x;i<=min(k*len,y);i++) tot+=(lon)val[i];
for(int i=bl[x]+;i<bl[y];i++) tot+=sum[i];
if(bl[x]==bl[y]) return tot;
k=bl[y];pushdown(k);
for(int i=(k-)*len+;i<=y;i++) tot+=(lon)val[i];
return tot;
} int querymax(int x,int y){
int maxn=-inf,k=bl[x];
pushdown(k);
for(int i=x;i<=min(k*len,y);i++) maxn=max(maxn,val[i]);
for(int i=bl[x]+;i<bl[y];i++) maxn=max(maxn,mx[i]);
if(bl[x]==bl[y]) return maxn;
k=bl[y];pushdown(k);
for(int i=(k-)*len+;i<=y;i++) maxn=max(maxn,val[i]);
return maxn;
} int querymin(int x,int y){
int minn=inf,k=bl[x];
pushdown(k);
for(int i=x;i<=min(k*len,y);i++)minn=min(minn,val[i]);
for(int i=bl[x]+;i<bl[y];i++) minn=min(minn,mn[i]);
if(bl[x]==bl[y]) return minn;
k=bl[y];pushdown(k);
for(int i=(k-)*len+;i<=y;i++) minn=min(minn,val[i]);
return minn;
} int main(){
scanf("%d%d",&n,&m);
len=sqrt(n);
for(int i=;i<=n/len+;i++){
mx[i]=-inf;
mn[i]=inf;
tag2[i]=-;
}
for(int i=;i<=n;i++){
scanf("%d",&val[i]);
bl[i]=(i-)/len+;
mx[bl[i]]=max(mx[bl[i]],val[i]);
mn[bl[i]]=min(mn[bl[i]],val[i]);
sum[bl[i]]+=(lon)val[i];
}
char op[];int x,y,z;
for(int i=;i<=m;i++){
scanf("%s%d%d",op,&x,&y);
if(op[]=='d'||op[]=='t') scanf("%d",&z);
if(op[]=='d') modify(x,y,z);
if(op[]=='t') change(x,y,z);
if(op[]=='m') printf("%lld\n",querysum(x,y));
if(op[]=='x') printf("%d\n",querymax(x,y));
if(op[]=='n') printf("%d\n",querymin(x,y));
}
return ;
}
线段树练习5(codevs 4927)的更多相关文章
- AC日记——线段树练习5 codevs 4927
4927 线段树练习5 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有n个数和5种操作 add a b ...
- T1081 线段树练习 2 codevs
http://codevs.cn/problem/1081/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数, ...
- AC日记——线段树练习三 codevs 1082 (分块尝试)
线段树练习 3 思路: 分块: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #incl ...
- AC日记——线段树练习4 codevs 4919
4919 线段树练习4 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 给你N个数,有两种操作 ...
- T1082 线段树练习3 codevs
http://codevs.cn/problem/1082/ 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 ...
- codevs 1080 线段树练习 CDQ分治
codevs 1080 线段树练习 http://codevs.cn/problem/1080/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 一行N个 ...
- Codevs 4927 线段树练习5(分块)
4927 线段树练习5 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有n个数和5种操作 add a b c:把区间[a,b]内的 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
随机推荐
- codevs 3344 迷宫
时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 小刚在迷宫内,他需要从A点出发,按顺序经过B,C,D……,到达最后一个点,再回到A ...
- 如何用JavaScript判断前端应用运行环境(移动平台还是桌面环境)
我们部署在某些云平台或者Web服务器上的前端应用,既可以用PC端浏览器访问,也可以用手机上的浏览器访问. 在前端应用里,有时候我们需要根据运行环境的不同做出对应处理.比如下面这段逻辑,如果判断出应用当 ...
- 使用python查询天气
python主代码 weather.py import urllib2 import json from city import city cityname = raw_input('你想查哪个城市的 ...
- Android(java)学习笔记148:网易新闻RSS客户端应用编写逻辑过程
1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,bl ...
- java上传、下载、删除ftp文件
一共三个类,一个工具类Ftputil.,一个实体类Kmconfig.一个测试类Test 下载地址:http://download.csdn.net/detail/myfmyfmyfmyf/669710 ...
- 简单css动画 fadeIn fadeOut flash
考虑兼容性采用 -webkit- -o- -mos- -ms- @keyframes fadeIn{ 0%{ opacity: 0; display: block; } 100%{ opacity: ...
- [HIHO] 1050 树中的最长路
#1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...
- (55)zabbix模板嵌套
在zabbix使用过程中,在某些情况下,一个host需要link多个模板.这么做显得比较麻烦,很容易忘记到底要link哪些模板,我想link一个模板就达成这个目标,行不行?然没问题,zabbix模板内 ...
- 【php】关于尾部去除和分号问题
One thing to remember is, if you decide to omit the closing PHP tag, then the last line of the file ...
- Python日志(logging)模块,shelve,sys模块
菜鸟学python第十七天 1.logging 模块 logging模块即日志记录模块 用途:用来记录日志 为什么要记录日志: 为了日后复查,提取有用信息 如何记录文件 直接打开文件,往里写东西 直接 ...