题目描述 Description

有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]的最小值

输入描述 Input Description

第一行两个整数n,m,第二行n个整数表示这n个数的初始值

接下来m行操作,同题目描述

输出描述 Output Description

对于所有的sum、max、min询问,一行输出一个答案

样例输入 Sample Input

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

样例输出 Sample Output

49

11

4

数据范围及提示 Data Size & Hint

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)的更多相关文章

  1. AC日记——线段树练习5 codevs 4927

    4927 线段树练习5  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 有n个数和5种操作 add a b ...

  2. T1081 线段树练习 2 codevs

    http://codevs.cn/problem/1081/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数, ...

  3. AC日记——线段树练习三 codevs 1082 (分块尝试)

    线段树练习 3 思路: 分块: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #incl ...

  4. AC日记——线段树练习4 codevs 4919

    4919 线段树练习4  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给你N个数,有两种操作 ...

  5. T1082 线段树练习3 codevs

    http://codevs.cn/problem/1082/ 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 ...

  6. codevs 1080 线段树练习 CDQ分治

    codevs 1080 线段树练习 http://codevs.cn/problem/1080/  时间限制: 1 s  空间限制: 128000 KB   题目描述 Description 一行N个 ...

  7. Codevs 4927 线段树练习5(分块)

    4927 线段树练习5 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有n个数和5种操作 add a b c:把区间[a,b]内的 ...

  8. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  9. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

随机推荐

  1. codevs 1277 生活大爆炸 2012年CCC加拿大高中生信息学奥赛

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题目描述 Description Sheldon and Leonard are physicists wh ...

  2. (七)mybatis之创建SqlSession

    前文提到了SqlSessionFactory接口,可以用来生产SqlSession.而SqlSession其实也是一个接口类,也就是起到一个门面的角色.那么谁是真正干活的呢?------Executo ...

  3. CNNs 在图像分割中应用简史: 从R-CNN到Mask R-CNN

    作者:嫩芽33出处:http://www.cnblogs.com/nenya33/p/6756024.html 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同意,必须保留此段声明:必须 ...

  4. lwz-过去一年的总结(15-16)

    今天2016年2月6日,还有1个半小时的时间,就要离开这个工作了9个月的地方,准备前往下个城市了.趁着这点时间,来给过去的一年做个即兴的总结吧. 2015年的2月份,在以前同学的提议和支持下,我重新学 ...

  5. hibernate4+spring3+struts2搭建框架实例

    1.所需要的JAR包 2.web.xml配置文件,这个和平时的配置是一样的 <?xml version="1.0" encoding="UTF-8"?&g ...

  6. ios之键盘的自定义

    一.键盘通知 当文本View(如UITextField,UITextView,UIWebView内的输入框)进入编辑模式成为first responder时,系统会自动显示键盘.成为firstresp ...

  7. javascript顺序数组简单实现个二分查找

    直接上码了注释写得很详细: function bsearch(A,x){ //l:查找范围左 r:查找范围右 let l = 0, //查询范围左边界 r = A.length-1, //查找范围右边 ...

  8. CF-1096C Polygon for the Angle

    CF-1096C Polygon for the Angle https://codeforces.com/contest/1096/problem/C 题意:给一个角度ang(1<=ang&l ...

  9. 【树形dp】bzoj1304: [CQOI2009]叶子的染色

    又是一道优美的dp Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的 ...

  10. Mac OSX: 有线共享WiFi

    首先连上有线 系统偏好设置->网络->点击左侧WiFi,再点击右下角[高级] 勾选[创建电脑对电脑网络],然后单击[好] 在顶部菜单栏击WiFi图标,如果WiFi未打开,则单击打开,如果已 ...