POJ 2481 Cows && POJ 2352 Stars(树状数组妙用)
题目链接:POJ 2481 Cows
发现这两个题目都跟求逆序数有着异曲同工之妙,通过向树状数组中插入点的位置,赋值为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; }