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个数做修改,第三个数为修改成 ...
随机推荐
- Codeforces Round #697 (Div. 3) G. Strange Beauty (DP,数学)
题意:给你一组数,问你最少删去多少数,使得剩下的数,每个数都能整除数组中其它某个数或被数组中其它某个数整除. 题解:我们直接枚举所有因子,\(dp[i]\)表示\(i\)在数组中所含的最大因子数(当我 ...
- Educational Codeforces Round 94 (Rated for Div. 2) String Similarity、RPG Protagonist、Binary String Reconstruction、Zigzags 思维
题目链接:String Similarity 题意: 首先题目定义了两个串的相似(串的构成是0.1),如果两个串存在对于一个下标k,它们的值一样,那么这两个串就相似 然后题目给你一个长度为2n-1的串 ...
- C. New Year Book Reading
New Year is coming, and Jaehyun decided to read many books during 2015, unlike this year. He has n b ...
- Codeforces Round #652 (Div. 2) B. AccurateLee(思维)
题意: 给你一个01字符串,现在你可以删除其中的一些子序列,要求如下:当遇到1 0的俩个连续子字符串后,可以删除其中的一个字符,现在要求把他删到尽量最短并且字典序最小,输出最后的字符串 题解: 刚开始 ...
- hdu5534 Partial Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submissi ...
- poj 2566 Bound Found 尺取法
一.首先介绍一下什么叫尺取 过程大致分为四步: 1.初始化左右端点,即先找到一个满足条件的序列. 2.在满足条件的基础上不断扩大右端点. 3.如果第二步无法满足条件则到第四步,否则更新结果. 4.扩大 ...
- [视频] FFMpeg 基本组成和入门示例
目录 FFmpeg基本组成 编解码工具 ffmpeg.exe ffmpeg.exe的工作流程 播放器 ffplay.exe 多媒体分析器 ffprobe FFmpeg基本组成 AVFormat 封装了 ...
- 关于free和delete的使用
上一篇篇幅太长,这里再区分free和delete的用法. 两个同时存在是有它的原因的,我们前面说过,free是函数,它只释放内存,但不会调用析构函数,如果用free去释放new申请的空间,会因为无法调 ...
- sentry can not delete release bug
sentry can not delete release bug bug $ ./node_modules/@sentry/cli/bin/sentry-cli releases list $ ./ ...
- JavaScript 实现 (ECMAScript 6)
JavaScript 的核心 ECMAScript 描述了该语言的语法和基本对象: DOM 描述了处理网页内容的方法和接口: BOM 描述了与浏览器进行交互的方法和接口. ECMAScript.DOM ...