HDOJ-1540(线段树+较复杂的单点修改和区间查询)
Tunnel Warfare
HDOJ-1540
- 这题关于线段树的操作有一定的难度,需要较好的思维能力。
- 关于题目的详细解答已经在代码中体现了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=50004;
int n,m;
int llen[maxn<<2];//左端点起的最大长度
int rlen[maxn<<2];//右端点起的最大长度
void pushup(int id,int l,int r){
int lc=id<<1;
int rc=id<<1|1;
int ch=r-l+1;//ch表示id(父亲)结点的覆盖长度
llen[id]=llen[lc];//左端点起的最大长度等于左儿子左端点起的最大长度
rlen[id]=rlen[rc];
if(llen[id]==ch-(ch>>1))//如果左儿子最大长度为结点整个区间,那么父亲结点要加上右儿子左端点起的最大长度
llen[id]+=llen[rc];
if(rlen[id]==(ch>>1)) //如果右儿子最大长度为结点整个区间,那么父亲结点要加上左儿子右端点起的最大长度
rlen[id]+=rlen[lc];
}
void build(int id,int l,int r){
if(l==r){
llen[id]=1;
rlen[id]=1;
return;
}
//长度全部初始化为结点覆盖的长度
llen[id]=r-l+1;
rlen[id]=r-l+1;
int mid=(l+r)>>1;
int lc=id<<1;int rc=id<<1|1;
build(lc,l,mid);
build(rc,mid+1,r);
}
void update(int id,int l,int r,int p,int v){
if(l==r){
llen[id]=v;
rlen[id]=v;
return;
}
int mid=(l+r)>>1;
int lc=id<<1;
int rc=id<<1|1;
if(p<=mid){
update(lc,l,mid,p,v);
}else{
update(rc,mid+1,r,p,v);
}
pushup(id,l,r);
}
int queryL(int id,int l,int r,int p,int q){//查询右边区间左端点起的最大长度
if(p<=l&&q>=r){
return llen[id];
}
int mid=(l+r)>>1;
int lc=id<<1;
int rc=id<<1|1;
if(q<=mid){//表示待查询的区间完全在左边
return queryL(lc,l,mid,p,q);
}else if(p>mid){//表示待查询的区间完全在右边
return queryL(rc,mid+1,r,p,q);
}else{//mid在待查询区间之内
int lans=queryL(lc,l,mid,p,mid);
int rans=queryL(rc,mid+1,r,mid+1,q);
if(lans==mid-p+1){//如果左区间最大长度为整个区间,这个时候才需要加上右边区间左端点起的最大长度
return lans+rans;
}else return lans;
}
}
int queryR(int id,int l,int r,int p,int q){//查询右边区间左端点起的最大长度
if(p<=l&&q>=r){
return rlen[id];
}
int mid=(l+r)>>1;
int lc=id<<1;
int rc=id<<1|1;
if(q<=mid){
return queryR(lc,l,mid,p,q);
}else if(p>mid){
return queryR(rc,mid+1,r,p,q);
}else{
int lans=queryR(lc,l,mid,p,mid);
int rans=queryR(rc,mid+1,r,mid+1,q);
if(rans==q-mid){//同理,如果有区间的最大长度为整个区间,这个时候才需要加上左边区间右端点起的最大长度
return lans+rans;
}else return rans;
}
}
int main(){
while(cin>>n>>m){
vector<int> v;
build(1,1,n);
for(int i=0;i<m;i++){
char c;int x;
cin>>c;
if(c=='D'){//update
cin>>x;
v.push_back(x);
update(1,1,n,x,0);
}else if(c=='Q'){//query
cin>>x;
int ans=queryL(1,1,n,x,n)+queryR(1,1,n,1,x);//相当于查询左边区间右端点起最大长度加上右边区间左端点起最大长度
cout<<(ans>0?ans-1:0)<<endl;
}else if(c=='R'&&v.size()>0){//update
x=v[v.size()-1];
v.pop_back();
update(1,1,n,x,1);
}
}
}
return 0;
}
HDOJ-1540(线段树+较复杂的单点修改和区间查询)的更多相关文章
- 线段树:Segment Tree(单点修改/区间修改模板) C++
线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...
- P3374 【模板】树状数组 1 单点修改与区间查询
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...
- Billboard HDU - 2795(树状数组,单点修改,区间查询)
题目链接:https://vjudge.net/problem/HDU-2795 思路:h = 1e9行不通,因为广告是1*w的,所以n个广告最多只需要 h = n的高度,那么h=2e5就可以接受了. ...
- 【模板】cdq分治代替树状数组(单点修改,区间查询)
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #in ...
- 【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵
https://vjudge.net/contest/66989#problem/A 单点修改,区间查询 方法一:线段树 http://www.cnblogs.com/kuangbin/archive ...
- HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)
HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...
- HDU - 1166 敌兵布阵 方法一:(线段树+单点修改,区间查询和) 方法二:利用树状数组
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...
- ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)
1.给了每条线段的颜色,存在颜色覆盖,求表面上能够看到的颜色种类以及每种颜色的段数. 2.线段树区间更新,单点查询. 但是有点细节,比如: 输入: 2 0 1 1 2 3 1 输出: 1 2 这种情况 ...
- 校内模拟赛T5:连续的“包含”子串长度( nekameleoni?) —— 线段树单点修改,区间查询 + 尺取法合并
nekameleoni 区间查询和修改 给定N,K,M(N个整数序列,范围1~K,M次查询或修改) 如果是修改,则输入三个数,第一个数为1代表修改,第二个数为将N个数中第i个数做修改,第三个数为修改成 ...
随机推荐
- poj3087 Shuffle'm Up
Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuff ...
- Codeforces Round #327 (Div. 1) C. Three States
C. Three States time limit per test 5 seconds memory limit per test 512 megabytes input standard inp ...
- XML、DTD约束
XML的作用: xml现在主要用于配置文件 文档声明: 如果你使用记事本打开文档,此时如果记事本默认保存数据到硬盘根据的是"GB2312"编码,这个时候如果你在xml文档源码中en ...
- Entity Framework (EF) Core学习笔记 1
1. Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台的数据访问技术,它还是一 种对象关系映射器 (ORM),它使 .NET 开发人员能够使用面向对象的思想处理数据 ...
- Python 往Excel写数据
一.需求描述: 1.一张人员信息表中生成人员信息,某些列的字段要进行递增操作: 2.一个组织节点下存在1000人的限制要求: 3.一张Excel表格生成45000条数据: 二.Excel表格的表头如下 ...
- Please commit your changes or stash them before you merge问题解决
问题描述 error: Your local changes to the following files would be overwritten by merge: xxx/xxx/xxx.c P ...
- Leetcode(94)-二叉树的中序遍历
给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 思路:和上篇的前序遍历一样,同样有递归和非递归的做法 (1)递归 vecto ...
- 2019牛客多校第三场F Planting Trees(单调队列)题解
题意: 求最大矩阵面积,要求矩阵内数字满足\(max - min < m\) 思路: 枚举上下长度,在枚举的时候可以求出每一列的最大最小值\(cmax,cmin\),这样问题就变成了求一行数,要 ...
- 还傻傻分不清楚equals和==的区别吗?看完就明白了
解决一个问题的最好方法就是发现一个问题产生的根源,即发现最本质的东西,再去解决它. Java语言里面的equals()方法是交给开发者们自己去覆盖重写编写功能的,即让开发者去定义当满足什么条件时,两个 ...
- Keras模型拼装
在训练较大网络时, 往往想加载预训练的模型, 但若想在网络结构上做些添补, 可能出现问题一二... 一下是添补的几种情形, 此处以单输出回归任务为例: # 添在末尾: base_model = Inc ...