分块试水--CODEVS4927 线段树练习5
模板
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<math.h>
//#include<bitset>
//#include<iostream>
using namespace std; int n,m,q;
#define maxn 100011
#define maxm 361
#define LL long long
const LL inf=1e18;
LL a[maxn],add[maxm],be[maxm],sum[maxm],Max[maxm],Min[maxm]; bool hasbe[maxm];
int bel[maxn],tot; void down(int x)
{
int l=(x-)*m+,r=min(x*m,n);
for (int i=l;i<=r;i++)
{
if (add[x]) a[i]+=add[x];
else if (hasbe[x]) a[i]=be[x];
}
add[x]=hasbe[x]=;
}
void up(int x)
{
int l=(x-)*m+,r=min(x*m,n);
sum[x]=; Max[x]=-inf; Min[x]=inf;
for (int i=l;i<=r;i++)
sum[x]+=a[i],Max[x]=max(Max[x],a[i]),Min[x]=min(Min[x],a[i]);
}
void Addsingle(int x,int y,int v)
{
down(bel[x]);
for (int i=x;i<=y;i++) a[i]+=v;
up(bel[x]);
}
void Add(int x,int y,int v)
{
if (bel[x]==bel[y]) Addsingle(x,y,v);
else
{
int j;
for (j=x;bel[j]==bel[x];j++);
Addsingle(x,j-,v);
for (j=y;bel[j]==bel[y];j--);
Addsingle(j+,y,v);
for (int i=bel[x]+;i<bel[y];i++)
{
if (hasbe[i]) be[i]+=v;
else add[i]+=v;
sum[i]+=1ll*m*v;
Max[i]+=v; Min[i]+=v;
}
}
}
void Besingle(int x,int y,int v)
{
down(bel[x]);
for (int i=x;i<=y;i++) a[i]=v;
up(bel[x]);
}
void Be(int x,int y,int v)
{
if (bel[x]==bel[y]) Besingle(x,y,v);
else
{
int j;
for (j=x;bel[j]==bel[x];j++);
Besingle(x,j-,v);
for (j=y;bel[j]==bel[y];j--);
Besingle(j+,y,v);
for (int i=bel[x]+;i<bel[y];i++)
{
if (add[i]) add[i]=;
hasbe[i]=; be[i]=v;
sum[i]=1ll*m*v;
Max[i]=Min[i]=v;
}
}
}
LL qsumsingle(int x,int y)
{
LL ans=;
for (int i=x;i<=y;i++)
{
if (hasbe[bel[i]]) ans+=be[bel[i]];
else ans+=a[i]+add[bel[i]];
}
return ans;
}
LL qsum(int x,int y)
{
if (bel[x]==bel[y]) return qsumsingle(x,y);
else
{
int j;
for (j=x;bel[j]==bel[x];j++);
LL ans=qsumsingle(x,j-);
for (j=y;bel[j]==bel[y];j--);
ans+=qsumsingle(j+,y);
for (int i=bel[x]+;i<bel[y];i++) ans+=sum[i];
return ans;
}
}
LL qmaxsingle(int x,int y)
{
LL ans=-inf;
for (int i=x;i<=y;i++)
{
if (hasbe[bel[i]]) ans=max(ans,be[bel[i]]);
else ans=max(ans,a[i]+add[bel[i]]);
}
return ans;
}
LL qmax(int x,int y)
{
if (bel[x]==bel[y]) return qmaxsingle(x,y);
else
{
int j;
for (j=x;bel[j]==bel[x];j++);
LL ans=qmaxsingle(x,j-);
for (j=y;bel[j]==bel[y];j--);
ans=max(ans,qmaxsingle(j+,y));
for (int i=bel[x]+;i<bel[y];i++) ans=max(ans,Max[i]);
return ans;
}
}
LL qminsingle(int x,int y)
{
LL ans=inf;
for (int i=x;i<=y;i++)
{
if (hasbe[bel[i]]) ans=min(ans,be[bel[i]]);
else ans=min(ans,a[i]+add[bel[i]]);
}
return ans;
}
LL qmin(int x,int y)
{
if (bel[x]==bel[y]) return qminsingle(x,y);
else
{
int j;
for (j=x;bel[j]==bel[x];j++);
LL ans=qminsingle(x,j-);
for (j=y;bel[j]==bel[y];j--);
ans=min(ans,qminsingle(j+,y));
for (int i=bel[x]+;i<bel[y];i++) ans=min(ans,Min[i]);
return ans;
}
}
int main()
{
scanf("%d%d",&n,&q);
m=(int)sqrt(n);
for (int i=;i<=n;i++) bel[i]=(i-)/m+;
tot=bel[n];
for (int i=;i<=tot;i++) Max[i]=-inf,Min[i]=inf;
for (int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[bel[i]]+=a[i];
Max[bel[i]]=max(Max[bel[i]],a[i]);
Min[bel[i]]=min(Min[bel[i]],a[i]);
} char c[];int x,y,z;
while (q--)
{
scanf("%s%d%d",c,&x,&y);
if (c[]=='a') scanf("%d",&z),Add(x,y,z);
else if (c[]=='e') scanf("%d",&z),Be(x,y,z);
else if (c[]=='u') printf("%lld\n",qsum(x,y));
else if (c[]=='a') printf("%lld\n",qmax(x,y));
else printf("%lld\n",qmin(x,y));
}
return ;
}
分块试水--CODEVS4927 线段树练习5的更多相关文章
- 分块试水--CODEVS5037 线段树练习4加强版
感觉这才算入门题吧..前面那些线段树练习,改几个字符就过了一定要搞成几道题.. n<=2e5的数列,给常数K<=2e5,m<=2e5个操作,区间加,问一个区间里K的倍数. 这题空间? ...
- codevs4927 线段树练习5
题目描述 Description 有n个数和5种操作 add a b c:把区间[a,b]内的所有数都增加c set a b c:把区间[a,b]内的所有数都设为c sum a b:查询区间[a,b] ...
- 51NOD 1287 加农炮(不水的线段树)
>>点击进入原题测试<< Input示例 Output示例 思路:刚开始以为结点存最大值就行了,然后大于左子树的最大值就能进入右子树:然后发现样例都过不了:后面发现,并不是这个 ...
- 【wikioi】1191 数轴染色(线段树+水题)
http://wikioi.com/problem/1191/ 太水的线段树了,敲了10分钟就敲完了,但是听说还有一种并查集的做法?不明觉厉. #include <cstdio> #inc ...
- 2014 Super Training #9 F A Simple Tree Problem --DFS+线段树
原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个ma ...
- 【线段树】Bzoj1230 [Usaco2008 Nov]lites 开关灯
Description Farmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛们思维敏捷. 其中一个大型玩具是牛栏中的灯. N (2 <= N <= 100,000) 头奶牛中的每 ...
- [CF52C]Circular RMQ【线段树】
题目大意 给你一个环形数列,完成环形数列上区间加法和区间求最小值. 分析 算是一道比较水的线段树模板题. 如果l>r的话,那么修改l,n和1,r区间. 不然的话那么就修改l,r区间. 其他的基础 ...
- P2801 教主的魔法 (线段树)
题目 P2801 教主的魔法 解析 成天做水题 线段树,第一问区间加很简单 第二问可以维护一个区间最大值和一个区间最小值,若C小于等于区间最小值,就加上区间长度,若C大于区间最大值,就加0 ps:求教 ...
- HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护
给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示d ...
随机推荐
- mysql 的索引hash和b+tree 区别
索引hash相当于数组,键值对组合,对于id = 6或者status= 2这样条件查询,但是对于id>12等这样,用btree索引最好.
- 微信小程序资源
1.http://blog.csdn.net/wyx100/article/details/52667518 2.http://mp.weixin.qq.com/s?__biz=MzIyMDM2Mjg ...
- DHTML_____document对象的方法
<html> <head> <meta charset="utf-8"> <title>document对象的方法</titl ...
- scala学习笔记3:基本控制结构基础
以下主要记录的是看完scala in programming这本书buildin control structures(第七章)后的要点总结. 1,if,while,do while和for的用法和j ...
- 计算给定数组 arr 中所有元素的总和的几种方法
1.forEach遍历: function sum(arr) { var result = 0; arr.forEach(function(item,index) { ...
- opencv总结
2018-02-2623:59:02 唉,这软件我很烦躁,今天又搞了好几遍,出错提示的时候总是出问题! 而且,无论什么错误,都是提示一堆乱码! 定义ROI区域有两种方法,第一种是使用cv:Rect.顾 ...
- 百度人脸识别AI实践.doc
0, 前言 百度开放了很多AI能力,其中人脸识别就是其中之一. 本文对百度人脸识别AI进行实践检验,看看其使用效果如何. 鉴于是最为基础的实践,基本都是在其接口范例代码修改而来. 百度人脸识别AI网站 ...
- java 物理分页和逻辑分页
A.逻辑分页利用游标分页,好处是所有数据库都统一,坏处就是效率低.1.逻辑分页的第一种方式,利用ResultSet的滚动分页.这种分页方式依靠的是对结果集的算法来分页,因此通常被称为“逻辑分页”.步骤 ...
- RabbitMQ调用
添加 gradle依赖complie("com.rabbitmq:amqp-client:5.0.0") Hello, World Working Queues Publish/S ...
- 如何安装Ant,配置环境变量??
Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发. Ant是一个基于Java,并且主要用于Java工程的构建工具.Ant本意是A ...