题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540

题目:

题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的村庄相连接的城市数量。

思路:线段树+区间合并。

代码实现如下:

 #include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define bug printf("*********\n");
#define FIN freopen("D://code//in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = 1e8;
const int maxn = 5e4 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-') f = -, c = getchar();
for(; isdigit(c); c = getchar()) ret = ret * + c - '';
if(f < ) ret = -ret;
return ret;
} int n, q, x, t;
char op[];
int tack[maxn]; struct node {
int l, r, mx, ls, rs; //ls为左端最大连续区间,rs为右端最大连续区间,mx为区间内最大连续区间
}segtree[maxn*]; void build(int i, int l, int r) {
segtree[i].l = l, segtree[i].r = r;
segtree[i].mx = segtree[i].ls = segtree[i].rs = r - l + ;
if(l == r) return;
int mid = (l + r) >> ;
build(lson);
build(rson);
} void update(int i, int pos, int x) {
if(segtree[i].l == segtree[i].r) {
if(x == ) segtree[i].mx = segtree[i].ls = segtree[i].rs = ; //此处为修复操作
else segtree[i].mx = segtree[i].ls = segtree[i].rs = ; //摧毁操作
return;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(pos <= mid) {
update(i * , pos, x);
} else {
update(i * + , pos, x);
}
segtree[i].ls = segtree[i*].ls;
segtree[i].rs = segtree[i*+].rs;
segtree[i].mx = max(max(segtree[i*].mx, segtree[i*+].mx), segtree[*i].rs + segtree[i*+].ls);
if(segtree[i*].ls == segtree[i*].r - segtree[i*].l + ) { //如果左端全是连接的,那么ls还要右子树的ls
segtree[i].ls += segtree[i*+].ls;
}
if(segtree[i*+].rs == segtree[i*+].r - segtree[i*+].l + ) { //同理
segtree[i].rs += segtree[i*].rs;
}
} int query(int i, int pos) {
if(segtree[i].l == segtree[i].r || segtree[i].mx == segtree[i].r - segtree[i].l + || segtree[i].mx == ) {
return segtree[i].mx;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(pos <= mid) {
if(pos >= segtree[*i].r - segtree[i*].rs + ) { //如果pos与右边连接,那么还需要跑另一棵子树
return query(i * , pos) + query(i * + , mid + );
} else {
return query(i * , pos);
}
} else {
if(pos <= segtree[i * + ].l + segtree[i*+].ls - ) { //同理
return query(i * + , pos) + query(i * , mid);
} else {
return query(i * + , pos);
}
}
} int main() {
//FIN;
while(~scanf("%d%d", &n, &q)) {
build(, , n);
t = ;
while(q--) {
scanf("%s", op);
if(op[] == 'D') {
scanf("%d", &x);
tack[++t] = x;
update(, x, );
} else if(op[] == 'R') {
if(t > ) {
x = tack[t--];
update(, x, );
}
} else {
scanf("%d", &x);
printf("%d\n", query(, x));
}
}
}
return ;
}

Tunnel Warfare(HDU1540+线段树+区间合并)的更多相关文章

  1. hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

    Tunnel Warfare                                                             Time Limit: 4000/2000 MS ...

  2. HDU - 1540 Tunnel Warfare(线段树区间合并)

    https://cn.vjudge.net/problem/HDU-1540 题意 D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 分析 线段树的区间内,我 ...

  3. HDU 1540 Tunnel Warfare(线段树+区间合并)

    http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目大意:抗日战争期间进行地道战,存在n个村庄用地道连接,输入D表示破坏某个村庄(摧毁与其相连的地道, 包 ...

  4. hdu 1540 Tunnel Warfare (线段树 区间合并)

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  5. HDU--1540 Tunnel Warfare(线段树区间更新)

    题目链接:1540 Tunnel Warfare 以为单组输入 这个题多组输入 结构体记录每个区间左边和右边的连续区间 ms记录最大 在查询操作时: 1.这个点即将查询到右区间 看这个点 x 是否存在 ...

  6. HDU1540 Tunnel Warfare(线段树区间维护&求最长连续区间)题解

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  7. hdu1540-Tunnel Warfare (线段树区间合并)

    题意:n个村庄,有三种操作,D x 破坏位置为x的村庄,R 修复上一次被破坏的村庄,Q x 输出含有x村庄的连续村庄的最大个数.线段树搞之,区间合并. ls[maxn]为当前节点左面的连续区间,rs[ ...

  8. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  9. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

随机推荐

  1. 3dContactPointAnnotationTool开发日志(十)

      要是那几个状态栏不能拖动的话岂不是显得太呆板了,于是我又参考Unity官方视频教程学习了如何实现拖动状态栏的功能,还挺简单的.   比如说要拖动这个PanelStatus面板,我只让使用者通过拖动 ...

  2. vue服务端渲染简单入门实例

    想到要学习vue-ssr的同学,自不必多说,一定是熟悉了vue,并且多多少少做过几个项目.然后学习vue服务端渲染无非解决首屏渲染的白屏问题以及SEO友好. 话不多说,笔者也是研究多日才搞明白这个服务 ...

  3. ubuntu搭建eclipse+svn

    最近工作中要求使用ubuntu系统进行开发,小编第一次使用,将搭建环境的过程中一点点经验分享给大家.ubuntu的使用跟linux差不太多,大多数命令还是一样的.不过界面要好看很多,O(∩_∩)O哈哈 ...

  4. Java-通过比较throw与throws来阐述抛出异常

    转自:http://www.cnblogs.com/Miracle-Maker/p/6239346.html 浅谈Java异常 以前虽然知道一些异常的处理,也用过一些,但是对throw和throws区 ...

  5. 网络控制API 路由表 arp表 包括tcp的这些参数都是从哪里设置

    路由表查看 arp缓存 都是走的什么接口?

  6. 发送tcp的时候,数据包是如何拷贝的

    发送数据包的时候,用户态的数据包是如何拷贝到内核的kiovec msghd 结构体 icmp是走sock吗? 每一个skb_buffer的大小都是固定的吗?所以有skb_available这样的函数 ...

  7. 【SQLAlchemy】SQLAlchemy修改查询字段列名

    SQLAlchemy问题记录 company price quantity Microsoft Google Google Google 要实现脚本 select price, sum(quantit ...

  8. POJ3057:Evacuation——题解

    http://poj.org/problem?id=3057 题目大意: .为人,D为门,X为障碍,门每秒只能出去一个人,问多少秒出光. 如果无法出光输出impossible. ——————————— ...

  9. GDI & GDI+

    GDI GDI绘图中的映射模式CDC::SetMapMode() GDI编程小结 GDI+ GDI+小例子 关于GDI+ GDI+编程小结

  10. BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MB Submit: 3446  Solved: 1692 [Submit][Sta ...