hdu acm 1540
发现线段树好难啊
抄的代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
using namespace std;const int maxn = 50000+10;int n,m;
int s[maxn],top;//s为模拟栈struct node
{int l,r;int ls,rs,ms;//ls,左端最大连续区间,rs右端最大连续区间,ms区间内最大连续区间
} a[maxn<<2];void init(int l,int r,int i)
{a[i].l = l;a[i].r = r;a[i].ls = a[i].rs = a[i].ms = r-l+1;if(l!=r){int mid = (l+r)>>1;init(l,mid,i*2);init(mid+1,r,2*i+1);}
}void insert(int i,int t,int x)
{if(a[i].l == a[i].r){if(x==1)a[i].ls = a[i].rs = a[i].ms = 1;//修复elsea[i].ls = a[i].rs = a[i].ms = 0;//破坏return ;}int mid = (a[i].l+a[i].r)>>1;if(t<=mid)insert(2*i,t,x);elseinsert(2*i+1,t,x);a[i].ls = a[2*i].ls;//左区间a[i].rs = a[2*i+1].rs;//右区间a[i].ms = max(max(a[2*i].ms,a[2*i+1].ms),a[2*i].rs+a[2*i+1].ls);//父亲区间内的最大区间必定是,左子树最大区间,右子树最大区间,左右子树合并的中间区间,三者中最大的区间值if(a[2*i].ls == a[2*i].r-a[2*i].l+1)//左子树区间满了的话,父亲左区间要加上右孩子的左区间a[i].ls += a[2*i+1].ls;if(a[2*i+1].rs == a[2*i+1].r-a[2*i+1].l+1)//同理a[i].rs += a[2*i].rs;
}int query(int i,int t)
{if(a[i].l == a[i].r || a[i].ms == 0 || a[i].ms == a[i].r-a[i].l+1)//到了叶子节点或者该访问区间为空或者已满都不必要往下走了return a[i].ms;int mid = (a[i].l+a[i].r)>>1;if(t<=mid){if(t>=a[2*i].r-a[2*i].rs+1)//因为t<=mid,看左子树,a[2*i].r-a[2*i].rs+1代表左子树右边连续区间的左边界值,如果t在左子树的右区间内,则要看右子树的左区间有多长并返回return query(2*i,t)+query(2*i+1,mid+1);elsereturn query(2*i,t);//如果不在左子树的右边界区间内,则只需要看左子树}else{if(t<=a[2*i+1].l+a[2*i+1].ls-1)//同理return query(2*i+1,t)+query(2*i,mid);elsereturn query(2*i+1,t);}
}int main()
{int i,j,x;char ch[2];freopen("in.txt", "r", stdin);while(~scanf("%d%d",&n,&m)){top = 0;init(1,n,1);while(m--){scanf("%s",ch);if(ch[0] == 'D'){scanf("%d",&x);s[top++] = x;insert(1,x,0);}else if(ch[0] == 'Q'){scanf("%d",&x);printf("%d\n",query(1,x));}else{if(x>0){x = s[--top];insert(1,x,1);}}}}fclose(stdin);return 0;
}
但是为毛下面的WA
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <stdlib.h>using namespace std;const int MAX_N = 50005;int n, m;
int top;
int s[MAX_N];struct node {int l, r;//左端端点、右端端点 int ls, rs, ms;//左端最大连续区间、右端最大连续区间、区间内最大连续区间
}a[MAX_N<<2];void init(int l, int r, int i) {a[i].l = l;a[i].r = r;a[i].ls = a[i].rs = a[i].ms = r - l + 1;if(l != r) {int mid = (l + r) >> 1;init(l, mid, i * 2);//左儿子 init(mid+1, r, i * 2 + 1);//右儿子 }
}//x==1是修复,x==0是破坏; t是要更改的节点; i是当前区间的根节点
void modify(int i, int t, int x) {if(a[i].l == a[i].r) {//如果是叶子节点、根节点 if(x == 1)a[i].ls = a[i].rs = a[i].ms = 1;//修复 elsea[i].ls = a[i].rs = a[i].ms = 0;//破坏 return ;}int mid = (a[i].l + a[i].r) >> 1;if(t <= mid)//如果在左区间 modify(2 * i, t, x);else //如果在右区间 modify(2 * i + 1, t, x);a[i].ls = a[2 * i].ls;a[i].rs = a[2 * i + 1].rs;a[i].ms = max(max(a[2 * i].ms, a[2 * i + 1].ms), a[2 * i].rs + a[2 * i + 1].ls);if(a[2 * i].ls == a[2 * i].r - a[2 * i].l + 1)//左子树区间满了的话,父亲左区间要加上右孩子的左区间a[i].ls += a[2 * i + 1].ls;if(a[2 * i + 1].rs = a[2 * i + 1].r - a[2 * i + 1].l + 1)//同理 a[i].rs += a[2 * i].rs;
}int query(int i, int t) {if(a[i].l == a[i].r || a[i].ms == 0 || a[i].ms == a[i].r - a[i].l + 1)//到了叶子节点或者该访问区间为空或者已满都不必要往下走了return a[i].ms;int mid = (a[i].l + a[i].r) >> 1;if(t <= mid)if(t >= a[2 * i].r - a[2 * i].rs + 1)//因为t<=mid,看左子树,a[2*i].r-a[2*i].rs+1代表左子树右边连续区间的左边界值,如果t在左子树的右区间内,则要看右子树的左区间有多长并返回 return query(2 * i, t) + query(2 * i + 1, mid + 1);elsereturn query(2 * i, t);elseif(t <= a[2 * i + 1].l + a[2 * i + 1].ls - 1)return query(2 * i + 1, t) + query(2 * i, mid);elsereturn query(2 * i + 1, t);
}int main() {char ch[2];int x;freopen("in.txt", "r", stdin);while(~scanf("%d%d", &n, &m)) {top = 0;init(1, n, 1);while(m--) {scanf("%s", ch);if(ch[0] == 'D') {scanf("%d", &x);s[top++] = x;modify(1, x, 0);} else if(ch[0] == 'Q') {scanf("%d", &x);printf("%d\n", query(1, x));} else {if(x > 0) {x = s[--top];modify(1, x, 1);}}}}fclose(stdin);return 0;
}
hdu acm 1540相关推荐
- 杭电 HDU ACM 圆桌会议
圆桌会议 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- HDU ACM Steps 攻略
HDU ACM Steps 攻略- Admin 2011年10月14日 名人名言:未来是光明而美丽的,爱它吧,向它突进,为它工作,迎接它,尽可能地使它成为现实吧!--车尔尼雪夫斯基 总结了一下ACM ...
- HDU ACM 4031 Attack (树状数组--单点查询+区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=4031 用了树状数组的区间更新 单点查找(一般为单点更新 区间查找) 例如 区间(2,4)加1 则Updata(2 ...
- HDU ACM 1162 Eddy's picture
http://acm.hdu.edu.cn/showproblem.php?pid=1162 输入一个整数n,表示点的个数. 接下来n行,每行有两个浮点数表示点的x坐标y坐标. 构造一棵最小生成树. ...
- HDU ACM 1181 变形课 (广搜BFS + 动态数组vector)-------第一次使用动态数组vector
http://acm.hdu.edu.cn/showproblem.php?pid=1181 题意:给我若干个单词,若单词A的结尾与单词B的开头相同,则表示A能变成B,判断能不能从b开头变成m结尾. ...
- HDU ACM 1728 逃离迷宫 (广搜BFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意:给出一张图,转弯数k,起点(x1,y1),(x2,y2)判断能不能最多只转k个弯时从起点走到终点 输 ...
- HDU ACM 1224 Free DIY Tour (SPFA)
Free DIY Tour Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- HDU ACM 3986 Harry Potter and the Final Battle(邻接表实现最短路dijkstra堆优化记录路径 + 枚举最短路上每条边)...
http://acm.hdu.edu.cn/showproblem.php?pid=3986 题意: 从起点1 到 终点n,删除图中任意一条边求最短路的最坏情况. n --表示有n个点 m --边数 ...
- HDU ACM Steps攻略 ACM Steps的全部内容
原地址:http://www.byywee.com/page/M0/S607/607452.html 总结了一下ACM STEPS的各章内容,趁便附上我的Steps题号(每人的不一样). 别的,此文首 ...
- HDU ACM 3177 Crixalis's Equipment
Crixalis's Equipment Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
最新文章
- (转) 使用Speech SDK 5.1文字转音频
- 网页实时聊天之PHP如何实现websocket
- vscode MPE puppeteer导出pdf的数学公式显示问题
- 计算机网络的防雷保护,计算机网络机房如何防雷?为什么要防雷?防雷三级保护方案是哪三级?...
- 七、排序(3)——线性排序
- 在ABAP XSLT中调用ABAP类的方法
- (转)CocosCreator零基础制作游戏《极限跳跃》二、制作游戏开始场景
- msfconsole 无法启动,解决办法
- MySql Delimiter
- .NET 项目开发总结
- su、sudo、限制root远程登录
- 关于计算机的多媒体论文题目,浅谈计算机多媒体电子相册设计与制作(毕业论文)...
- linux下无法删除文件夹,linux服务器下完美解决无法删除虚拟主机文件或文件夹...
- [leetcode]169. 多数元素
- 【C++入门】C++ 运算符的重载
- 韩顺平Java基础入门笔记-第一章
- javascript语法
- Python A value is trying to be set on a copy of a slice from a DataFrame
- 用html做祝福语朋友,朋友友情祝福语
- 正定二次型与正定矩阵
热门文章
- 浅析SqlServer简单参数化模式下对sql语句自动参数化处理以及执行计划重用
- HDU-1009 做个骑士,以梦为马
- iOS 网络与多线程--3.异步Get方式的网络请求(非阻塞)
- 前台js限制上传图片质量大小和尺寸
- SQL2005企业版详细部署(一)
- Sql server 行列转换
- 感受McAfee.Secure.Internet.Gateway
- 微型计算机2011 24,微型计算机及接口技术2011年1月真题试题(04732)
- mysql linq 事务_一步一步学Linq to sql(七):并发与事务
- python 自动执行 apdl_在高效的mann中从Python运行ANSYS Mechanical APDL