POJ 2481 Cows && POJ 2352 Stars(树状数组妙用)

题目链接:POJ 2481 Cows

                    POJ 2352 Stars


发现这两个题目都跟求逆序数有着异曲同工之妙,通过向树状数组中插入点的位置,赋值为1,或者++,然后通过求和来判断比当前 点 ”“ 的有多少点。


Cows需要自己排序, Stars题目已经给排好序。


POJ 2352 Stars


题目大意为在二维坐标上给出一些星星的坐标,求某一个星星左方,下方,左下方的星星个数。题目已经把星星按照Y坐标从小到大,X从小到大排序。因此,在每次对一个星星进行统计时,之前出现过的星星,只要X坐标比其小,则必在其左,下,左下方。

树状数组储存X的坐标。 就像 求逆序数 的方法一样, 统计有多少之前的星星的X坐标小于当前的X坐标。

需要注意的是 X 坐标的范围是32000 ,所以树状数组要开到32000 而不是节点数15000。


【源代码】

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 32010;
int s[maxn];
int level[maxn];
	int n;
int lowbit(int x){
	return x&(-x);
}
int sum(int x){
	int ans = 0;
	for(int i=x;i>0;i-=lowbit(i)){
		ans+=s[i];
	}
	return ans;
}
void add(int x){
	for(int i=x;i<=maxn;i+=lowbit(i)){
		s[i]++;
	}
}
int main(){
	while(scanf("%d",&n)!=EOF){
		int a,b;
		memset(s,0,sizeof(s));
		memset(level,0,sizeof(level)); //初始化
		for(int i=1;i<=n;i++){
			scanf("%d%d",&a,&b);
			++a; //希望节点从1开始而不是0 ,所以++
			level[sum(a)]++; //直接将统计的数量当做level的下标
			add(a); //添加节点
		}
		for(int i=0;i<n;i++){
			printf("%d\n",level[i]);
		}
	}
	return 0;
}

POJ 2481 Cows


和上一题类似的思想,不过需要手动排序。具体怎么做只要上一题弄懂了应该很容易写出来。

坑点在于可能出现相同的区间,在统计的时候简单处理一下就好。


【源代码】

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
const int maxn = 100100;
struct node{
	int st,end;int id;
}cow[maxn];
int s[maxn];
int level[maxn];
int lowbit(int x){ return x&(-x);}
void add(int x){
	for(int i=x;i<=maxn;i+=lowbit(i))
		s[i]++;
}
int sum(int x){
	int ans=0;
	for(int i=x;i>0;i-=lowbit(i)){
		ans+=s[i];
	}
	return ans;
}
bool cmp(const node&a, const node&b){
	if(a.end==b.end)
		return a.st<b.st;
	return a.end>b.end;
}
int main(){
	while(scanf("%d",&n)!=EOF&&n){
		memset(s,0,sizeof(s));
		for(int i=1;i<=n;i++){
			scanf("%d%d",&cow[i].st,&cow[i].end);
			cow[i].st++; //希望节点从1开始 而不是0 ,所以++
			cow[i].id=i;
		}
		sort(cow+1,cow+n+1,cmp);
		for(int i=1;i<=n;i++){
			if(i>1&&cow[i].st==cow[i-1].st&&cow[i].end==cow[i-1].end){ //判重
				level[cow[i].id]=level[cow[i-1].id];
			}
			else
				level[cow[i].id]=sum(cow[i].st);
			add(cow[i].st);
		}
		for(int i=1;i<=n;i++)
		{
			if(i!=1)
				printf(" ");
			printf("%d",level[i]);
		}
		puts("");
	}
	return 0;
}





posted @ 2015-08-25 15:24  编程菌  阅读(162)  评论(0编辑  收藏  举报