HPU 1721: 感恩节KK专场——雪人的高度【线段树 离散化】
2015-11-30 18:26
477 查看
1721: 感恩节KK专场——雪人的高度
时间限制: 1 Sec 内存限制: 128 MB提交: 77 解决: 34
[提交][状态][讨论版]
题目描述
大雪过后,KK决定在春秋大道的某些区间上堆雪人。现在KK遇到了一道统计雪人高度的难题,请你帮帮他吧。注:KK堆雪人前春秋大道上是没有雪人的即所有位置雪人高度为0。输入
给定一个整数t,表示有t(t<=5)组测试数据。每组测试数据有两个整数N(1<=N<=200000),表示N次操作。操作分四种:
U1 x y v [x, y]位置的雪人高度减v
U2 x y v [x, y]位置的雪人高度加v
Q1 x y 查询[x, y]之间雪人的最大高度
Q2 x y 查询[x, y]之间雪人的最小高度
注: (|x|, |y|<=2^30, |v|<=100)
若上面的操作使某个位置的雪人高度为负,我们认为这种情况是合法的。
输出
对每个查询输出结果,结果占一行。结果保证不会超int。样例输入
1 2 U2 -1000 1000 1 Q1 1000 10001
样例输出
1
恩,线段树离散化,记录最大最小值,然后数组一定要开大
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 200020 using namespace std; int rec[maxn<<2],x[maxn],y[maxn];//离散化数组也要开大 int mark[maxn],v[maxn]; struct Node { int l,r,maxh,minh,c; }; Node node [maxn<<3];//数组之前开的maxn<<2就错 void pushup(int o) { node[o].maxh=max(node[o<<1].maxh,node[o<<1|1].maxh); node[o].minh=min(node[o<<1].minh,node[o<<1|1].minh); } void pushdown(int o) { if(node[o].c) { node[o<<1].c+=node[o].c; node[o<<1|1].c+=node[o].c; node[o<<1].maxh+=node[o].c; node[o<<1].minh+=node[o].c; node[o<<1|1].maxh+=node[o].c; node[o<<1|1].minh+=node[o].c; node[o].c=0; } } void build(int o,int l,int r) { node[o].l=l; node[o].r=r; node[o].c=0; node[o].maxh=node[o].minh=0; if(l==r) return ; int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); } void update(int o,int l,int r,int v) { if(node[o].l==l&&node[o].r==r) { node[o].maxh+=v; node[o].minh+=v; node[o].c+=v; return ; } pushdown(o); int mid=(node[o].l+node[o].r)>>1; if(r<=mid) update(o<<1,l,r,v); else if(l>mid) update(o<<1|1,l,r,v); else { update(o<<1,l,mid,v); update(o<<1|1,mid+1,r,v); } pushup(o); } int query(int o,int l,int r,int p) { if(node[o].l==l&&node[o].r==r) { if(p==1) return node[o].maxh; else return node[o].minh; } pushdown(o); int mid=(node[o].l+node[o].r)>>1; if(r<=mid) return query(o<<1,l,r,p); else if(l>mid) return query(o<<1|1,l,r,p); else { if(p==1) return max(query(o<<1,l,mid,p),query(o<<1|1,mid+1,r,p)); else return min(query(o<<1,l,mid,p),query(o<<1|1,mid+1,r,p)); } } int bsearch(int l,int r,int s) { while(l<=r) { int mid=(l+r)>>1; if(rec[mid]==s) return mid; if(rec[mid]>s) r=mid-1; else l=mid+1; } } int main() { int t,n; char s[10]; scanf("%d",&t); while(t--) { int k=0; scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%s",s); if(strcmp(s,"U1")==0) { scanf("%d%d%d",&x[i],&y[i],&v[i]); mark[i]=1; } else if(strcmp(s,"U2")==0) { scanf("%d%d%d",&x[i],&y[i],&v[i]); mark[i]=2; } else if(strcmp(s,"Q1")==0) { scanf("%d%d",&x[i],&y[i]); mark[i]=3; } else { scanf("%d%d",&x[i],&y[i]); mark[i]=4; } rec[++k]=x[i]; rec[++k]=y[i]; } sort(rec+1,rec+k+1); int j=2; for(int i=2;i<=k;++i) { if(rec[i]!=rec[i-1]) rec[j++]=rec[i]; } build(1,1,k); for(int i=0;i<n;++i) { int val; int l=bsearch(1,j-1,x[i]); int r=bsearch(1,j-1,y[i]); if(l>r) { int tem=l; l=r; r=tem; } if(mark[i]==1) { update(1,l,r,-v[i]); } else if(mark[i]==2) { update(1,l,r,v[i]); } else if(mark[i]==3) { printf("%d\n",query(1,l,r,1)); } else { printf("%d\n",query(1,l,r,2)); } } } return 0; }
相关文章推荐
- $.each遍历json对象
- poj 1438--One-way Traffic(边的双连通)
- 茅山光大大团队第二次冲刺进度展示
- jsp servlet的区别和联系(转)
- spark 中的RDD编程 -以下基于Java api
- qmake配置版本
- JSP 技术 —— 是敌是友?
- Fast Compressive Tracking(快速压缩跟踪)算法的C++代码实现
- Html与CSS布局技巧
- jquery中怎么删除<ul>中的整个<li>包括节点
- 《需求分析与系统设计》第三篇阅读体会
- Spark中的wordCount程序实现
- Android StartActivityForResult两个Activity相互跳转传递消息
- IOS_Swift_enum枚举方法
- HttpClient基本用法
- JSP 技术 -- 是友还是敌?
- 苹果私有函数使用初探
- Angular JS 学习笔记(一)
- 关于 python 的 @property总结和思考
- PostgreSQL WITH 临时表