poj 2352
来源:互联网 发布:恒鸿达软件 编辑:程序博客网 时间:2024/06/06 01:01
题目的意思是要算出每个节点的左方和下方共有多少个节点,由于题目当中节点的顺序是按x与y的升序给出的,所以只需按照输入顺序逐个处理节点即可。
对于每一个未处理的节点,每个已处理的节点必然在它的下侧或者左侧,所以在处理每一个节点时,只需要考虑该节点的左边有多少已处理的节点即可。用数学化的表示方法即是对于待处理节点(x, y),找出(0, x)内有多少个已处理的节点。
此题可以用两种方法,一是线段树,二是树状树组,其时间复杂度均为O(nlogn),不过树状树组的空间复杂度较小,而且代码实现上也比较简单。不过使用树状树组时需要注意,由于树状树组是由1开始计数的,而本题的坐标可以为0,所以再使用树状树组时,需要把每个点的横坐标平移一位。
树状数组的lowbit操作虽然功能简单,但是是一个频繁调用的操作,所以如果不写在函数里,而是直接使用x += x & (-x)或x -= x & (-x)效率会提高不少。
方法一:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_LEN = 32000;
const int MAXN = 65000;
const int MAXSTAR = 15000;
struct TreeNode {
intl, r;
intnum;
};
TreeNode tree[MAXN];
void makeTree(int st, int end, int treeNum){
tree[treeNum].l= st;
tree[treeNum].r= end;
tree[treeNum].num= 0;
if(end - st >= 1) {
intmid = (st + end) / 2;
makeTree(st,mid, treeNum * 2);
makeTree(mid+ 1, end, treeNum * 2 + 1);
}
return;
}
void insertTree(int x, int treeNum) {
tree[treeNum].num++;
if(tree[treeNum].l == tree[treeNum].r) {
return;
}
intmid = (tree[treeNum].l + tree[treeNum].r) / 2;
if(x <= mid) {
insertTree(x,treeNum * 2);
}else {
insertTree(x,treeNum * 2 + 1);
}
return;
}
int searchTree(int st, int end, inttreeNum) {
intiRes = 0;
intiMid;
TreeNode&i = tree[treeNum];
iMid= (i.l + i.r) / 2;
if(i.l == st && i.r == end) {
iRes= i.num;
}else {
if(end <= iMid) {
iRes+= searchTree(st, end, treeNum * 2);
}else if (st > iMid) {
iRes+= searchTree(st, end, treeNum * 2 + 1);
}else {
iRes+= searchTree(st, iMid, treeNum * 2);
iRes+= searchTree(iMid + 1, end, treeNum * 2 + 1);
}
}
returniRes;
}
int main(void) {
intn;
intlevel[MAXSTAR];
intiRes;
scanf("%d",&n);
intx, y;
makeTree(0,MAX_LEN, 1);
memset(level,0, sizeof(level));
for(int i = 1; i <= n; i++) {
scanf("%d%d",&x, &y);
iRes= searchTree(0, x, 1);
insertTree(x,1);
level[iRes]++;
}
for(int i = 0; i < n; i++) {
printf("%d\n",level[i]);
}
return0;
}
方法二:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 32010;
const int MAXN2 = 15010;
int tree[MAXN];
int level[MAXN2];
int lowbit(int x) {
returnx & (x ^ (x - 1));
}
int calSum(int x) {
intiAns;
iAns= 0;
for(int i = x; i > 0; i -= lowbit(i)) {
iAns+= tree[i];
}
returniAns;
}
void updateTree(int x) {
for(int i = x; i <= MAXN; i += lowbit(i)) {
tree[i]++;
}
return;
}
int main(void) {
intn;
intx, y;
scanf("%d",&n);
memset(tree,0, sizeof(tree));
memset(level,0, sizeof(level));
for(int i = 0; i < n; i++) {
scanf("%d%d",&x, &y);
x++;
level[calSum(x)]++;
updateTree(x);
}
for(int i = 0; i < n; i++) {
printf("%d\n",level[i]);
}
return0;
}
- poj 2352
- poj 2352
- poj 2352
- poj 2352
- poj 2352
- poj 2352
- poj 2352
- poj 2352
- poj 2352
- poj-2352
- POJ 2352
- poj 2352
- poj-2352
- poj 2352
- poj 2352
- POJ 2352
- poj 2352
- POJ 2352 STARS
- 孙子兵法——计篇
- 如何快速的和合作方进行接口开发
- 【asp.net小札记】jquery+ajax绑定数据库显示table
- Hadoop1.1.2 Eclipse 插件编译
- C语言运行时库详解 (C/C++ Runtime)
- poj 2352
- 加载URL获得页面源代码
- Android系统的开机画面显示过程分析
- IT行业中说话最不靠谱的商业领袖
- mysql日期格式化
- Direct9学习之-------------------------公告板技术
- Java System.LoadLibrary() 能否多次加载同一个动态库?
- opencv入门学习(将三张图像放在一起)
- coco2dx 2.0 解决 android多分辨率问题