POJ 2352 Stars (线段树)
来源:互联网 发布:通达信软件编程 编辑:程序博客网 时间:2024/06/08 10:41
URL: http://poj.org/problem?id=2352
题目大意:
给定n个点(n<=15000), 每个点有坐标(x, y) (0<=x, y<=32000), 规定每个点i的level等于满足x[j]<=x[i] && y[j]<=y[i]的点j的个数,求出level值为0, 1, 2, ..., n-1的点分别有几个. y以升序给出, y值相等的以x升序给出。
思路分析:
既然y值以升序给出,那问题就简化成了: 给定一个数列a, 求a[1]至a[i-1]共有多少个数在[0, i]之间。(然后统计一下即可)
不难观察到,线段树很适合处理此类问题。
把坐标看成区间,对[0,32000]的区间建线段树,树中的num记录[l, r]区间内的x的个数。(也可对[0,maxx]区间建树,但是要先求出maxx)
每次添加新的节点,找到x应该所在的那个节点,然后沿着递归之路每到一个节点就num++, 直到找到为止。
每次添加之前先询问,询问时求出区间[0,x]所跨子区间的num值之和。
由此算出level, 然后统计即可。
时间复杂度O(n log n).
部分易错点:
1. 线段树区间从0开始,而不是1.
2. 线段树的数组要开MAXN的4倍,MAXN = 32000 but not 15000
代码呈现:
(Time: 188 MS; Memory: 2248 K; Code: 1452 B)
#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 32000;struct Node{int left,right,num,tag;};int lvl[MAXN+2];struct SegmentTree{Node nd[MAXN*4+2];void init(){for(int i=1; i<=MAXN*4; i++){nd[i].left = nd[i].right = nd[i].num = 0;}}void build(int lbound,int rbound,int pos){nd[pos].left = lbound;nd[pos].right = rbound;if(lbound==rbound) return;int mid = (lbound+rbound)/2;build(lbound,mid,2*pos);build(mid+1,rbound,2*pos+1);}void addval(int lbound,int rbound,int val,int pos){nd[pos].num++;if(lbound==rbound) return;int mid = (nd[pos].left+nd[pos].right)/2;if(val<=mid) addval(lbound,mid,val,2*pos);else addval(mid+1,rbound,val,2*pos+1);}int query(int lbound,int rbound,int pos){int mid = (nd[pos].left+nd[pos].right)/2;if(lbound==nd[pos].left && rbound==nd[pos].right) return nd[pos].num; long long ans;if(rbound<=mid) ans = query(lbound,rbound,2*pos);else if(lbound>mid) ans = query(lbound,rbound,2*pos+1);else ans = query(lbound,mid,2*pos)+query(mid+1,rbound,2*pos+1);return ans;}};SegmentTree st;int a[MAXN+2];int n;int main(){int q,lbound,rbound,val;char flag[5];scanf("%d",&n);st.init();st.build(0,MAXN,1); //can be both [0,MAXN] or [0,MAXX]; MAXX is the maximum value of all xfor(int i=1; i<=n; i++){int x,y;scanf("%d%d",&x,&y);lvl[st.query(0,x,1)]++; //must be [0,x]st.addval(0,MAXN,x,1);}for(int i=0; i<n; i++){printf("%d\n",lvl[i]);} return 0;}
阅读全文
0 0
- poj-2352-Stars-线段树
- poj 2352 Stars 线段树
- poj 2352 Stars(线段树)
- POJ 2352 Stars 线段树
- POJ 2352-Stars(线段树)
- POJ 2352 Stars 线段树
- poj 2352 Stars(线段树)
- POJ 2352 Stars (线段树)
- poj 2352 Stars (线段树做法)
- POJ 2352 Stars (线段树)
- POJ 2352 Stars (线段树&想法题)
- POJ 2352 Stars 线段树 pascal
- POJ 2352 Stars(线段树)
- poj 2352 && hdu 1541 Stars 线段树
- poj 2352 Stars(线段树 )
- poj 2352 Stars 线段树基础
- poj 2352 Stars (树状数组/线段树)
- poj 2352 Stars (线段树#4/树状数组)
- python尝试从通联数据爬取信息并保存在mongodb数据库中
- c#设计模式之开放封闭原则
- JS数据类型、类型转换
- Java架构师必看的10本书
- turn.js学习手册
- POJ 2352 Stars (线段树)
- 虚拟内存
- 第十章:vue2中axios请求服务端数据
- 四海八荒,就是上神也需要电脑维修
- 【c++】友元关系和子类函数构造函数的写法
- Hdu 6148 Valley Numer 数位DP
- 10个Eclipse珍藏插件推荐
- 树莓派3 搭建bt下载机---利用 transmission-daemon
- php中获取主机名、协议及IP地址的方法 及mysql 1024错误解决