博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P1503 鬼子进村
阅读量:4484 次
发布时间:2019-06-08

本文共 3244 字,大约阅读时间需要 10 分钟。

洛谷 P1503 鬼子进村

Description

  • 描述 县城里有n个用地道相连的房子,第i个只与第i-1和第i+1个相连。这是有m个消息依次传来

    1、消息为D x:鬼子将x号房子摧毁了,地道被堵上。

    2、消息为R :村民们将鬼子上一个摧毁的房子修复了。

    3、消息为Q x:有一名士兵被围堵在x号房子中。

    李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。

Input

  • 第一行2个整数n,m(n,m<=50000)。

    接下来m行,有如题目所说的三种信息共m条。

Output

  • 对于每一个被围堵的士兵,输出该士兵能够到达的房子数。

Sample Input

7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4

Sample Output

1

0

2

4

题解:

  • 平衡树。
  • 终于脱离了模版题的范畴。这题如果想到用平衡树思路就很容易想到了。用Treap维护被摧毁的房子位置,D操作就插入位置,Q操作(设给的当前位置为x)的答案就是(x的后继 - x的前继 - 1)。R操作弄一个栈依题意模拟即可。
  • 还是一句话,平衡树的前继后继函数要巧用!
#include 
#include
#include
#include
#define N 50005using namespace std;struct T {int l, r, val, dat;} t[N];int n, m, root, tot;stack
stk;int read(){ int x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();} return x;}int New(int val){ t[++tot].val = val; t[tot].dat = rand(); return tot;}void zig(int &y){ int x = t[y].l; t[y].l = t[x].r, t[x].r = y, y = x;}void zag(int &x){ int y = t[x].r; t[x].r = t[y].l, t[y].l = x, x = y;}void insert(int &p, int val){ if(!p) {p = New(val); return;} if(val == t[p].val) return; if(val < t[p].val) { insert(t[p].l, val); if(t[t[p].l].dat > t[p].dat) zig(p); } else { insert(t[p].r, val); if(t[t[p].r].dat > t[p].dat) zag(p); }}void erase(int &p, int val){ if(!p) return; if(val == t[p].val) { if(t[p].l || t[p].r) { if(!t[p].r || t[t[p].l].dat > t[p].dat) zig(p), erase(t[p].r, val); else zag(p), erase(t[p].l, val); } else p = 0; return; } val < t[p].val ? erase(t[p].l, val) : erase(t[p].r, val);}int preNext(int op, int val){ int ans = op == 0 ? 2 : 1, p = root; while(p) { if(val == t[p].val) { if(!op && t[p].l) { p = t[p].l; while(t[p].r) p = t[p].r; ans = p; break; } else if(!op) break; if(op && t[p].r) { p = t[p].r; while(t[p].l) p = t[p].l; ans = p; break; } else if(op) break; } if(!op && t[p].val < val && t[p].val > t[ans].val) ans = p; if(op && t[p].val > val && t[p].val < t[ans].val) ans = p; p = val < t[p].val ? t[p].l : t[p].r; } return t[ans].val;}bool find(int p, int val){ if(!p) return 0; if(val == t[p].val) return 1; if(val < t[p].val) return find(t[p].l, val); else return find(t[p].r, val);}int main(){ cin >> n >> m; New(n + 1), New(0), root = 1, t[1].l = 2; for(int i = 1; i <= m; i++) { char c[2]; scanf("%s", c); if(c[0] == 'D') { int x = read(); insert(root, x); stk.push(x); } else if(c[0] == 'R') { erase(root, stk.top()); stk.pop(); } else if(c[0] == 'Q') { int x = read(); if(find(root, x)) printf("0\n"); else printf("%d\n", preNext(1, x) - preNext(0, x) - 1); } } return 0;}

转载于:https://www.cnblogs.com/BigYellowDog/p/11324588.html

你可能感兴趣的文章
Python之路【第九篇】堡垒机基础&数据库操作
查看>>
小教练教MM如何去掉你的小肚子
查看>>
JS跨域请求
查看>>
jmeter之Dummy Sampler
查看>>
MySQL 调优基础(四) Linux 磁盘IO
查看>>
为什么选择Android Studio 而是 Eclipse
查看>>
Linux 系统目录结构(二)
查看>>
数列分块入门 1
查看>>
PHP一个失败的类,解析。。。。
查看>>
DOMDocument类文件
查看>>
JS Closure 闭包
查看>>
bzoj 1578: [Usaco2009 Feb]Stock Market 股票市场【背包】
查看>>
hdu 3038 How Many Answers Are Wrong【带权并查集】
查看>>
二叉树的基本操作
查看>>
软件工程之寻找水王
查看>>
MSMQ 消息队列错误处理
查看>>
Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天、消息模块
查看>>
在VisualStudio 工具箱中隐藏用户控件
查看>>
C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较...
查看>>
with(nolock) 与 with(readpast) 与不加此2个的区别
查看>>