树状数组水题小结 Poj 2352 + 2481 + 3067
2013-07-18 09:54
381 查看
Poj 2352 Stars
题目链接:http://poj.org/problem?id=2352
题意:在输入的星星中统计出每颗星星的左下角的星星数(包括正左与正下),称为一个星星的等级,输出每个等级下的星星数.
思路:由于输入时有序:即优先y坐标升序,然后x升序,相当于每输入一个新的数据都不会对之前输入的星星的等级产生影响,也即当前横坐标比x小的星星的数量就是当前星星的等级
Poj 2481 Cows
题意:有N头牛 它们每个都有一个领域[S,E] 如果 Si <= Sj and Ej <= Ei ,说明i牛比j牛强壮 求对每头牛而言 有多少牛比它强壮
思路: 按e大到小排序,然后以s作为标记用以更新大于s的牛会有多少个
也就是si<=sj的时候就可以统计sj前面有多少头牛了
Poj 3067 Japan
题目链接:http://poj.org/problem?id=3067
题意:有两排城市,这两排之间有一些城市之间有连接的道路,给出所有道路,问有多少道路是相交的
思路:设每一条线为(Ni,Mi),将所有的线按照Mi降序排列,Mi相同的话,按照Ni降序排列,最后只处理Ni
每次统计的时候,从1统计到Ni-1.此时,左边的是比Ni小的,右边是比Ni的相应点(即Mi)大的,所以必与该线段有交点。
需要用__int64来记录答案个数
题目链接:http://poj.org/problem?id=2352
题意:在输入的星星中统计出每颗星星的左下角的星星数(包括正左与正下),称为一个星星的等级,输出每个等级下的星星数.
思路:由于输入时有序:即优先y坐标升序,然后x升序,相当于每输入一个新的数据都不会对之前输入的星星的等级产生影响,也即当前横坐标比x小的星星的数量就是当前星星的等级
#include <cstdio> #include <cstring> int n; int bit[32010],level[15005]; int lowbit (int x) { return x&(-x); } void Update (int k) { while (k<=32010) { bit[k]+=1; k+=lowbit(k); } } int Cal (int k) { int sum=0; while (k>0) { sum+=bit[k]; k-=lowbit(k); } return sum; } int main () { while (~scanf("%d",&n)) { memset(bit,0,sizeof(bit)); memset(level,0,sizeof(level)); int i,x,y; for (i=1;i<=n;i++) { scanf("%d%d",&x,&y); Update (++x); //树状数组下标从1开始 level[Cal(x)-1]++; } for (i=0;i<n;i++) printf("%d\n",level[i]); } return 0; }
Poj 2481 Cows
题意:有N头牛 它们每个都有一个领域[S,E] 如果 Si <= Sj and Ej <= Ei ,说明i牛比j牛强壮 求对每头牛而言 有多少牛比它强壮
思路: 按e大到小排序,然后以s作为标记用以更新大于s的牛会有多少个
也就是si<=sj的时候就可以统计sj前面有多少头牛了
#include <cstdio> #include <cmath> #include <cstdlib> #include <algorithm> #define max(a,b) ((a)>(b)?(a):(b)) using namespace std; const int N=100005; struct Node { int x,y,id; }data ; int n,xmax; //xmax记录x的最大值,减少更新树状数组时的运行次数 int bit ,ans ; int lowbit (int x) { return x&(-x); } /* int cmp(const void *a,const void *b) { if (((Node*)a)->y == ((Node*)b)->y) return ((Node*)a)->x-((Node*)b)->x; //x的升序 return ((Node*)b)->y-((Node*)a)->y; //y的降序 } */ bool cmp (Node a,Node b) { if (a.y==b.y) return a.x<b.x; //x降序 return a.y>b.y; //优先y升序 } void Update (int k) { while (k<=xmax) { bit[k]+=1; k+=lowbit(k); } } int Getsum (int k) { int sum=0; while (k>0) { sum+=bit[k]; k-=lowbit(k); } return sum; } void Deal () { int i; sort (data+1,data+n+1,cmp); // qsort (data+1,n,sizeof(data[0]),cmp); Update (data[1].x); //该点一定最小,其ans数组一定为0,故不需在循环中计算 for (i=2;i<=n;i++) { if (data[i].x==data[i-1].x && data[i].y==data[i-1].y) //遇到重复的直接更新答案,不再计算 ans[data[i].id]=ans[data[i-1].id]; else ans[data[i].id]=Getsum(data[i].x); Update (data[i].x); //但仍然需要插入 } for (i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",ans[i]); } int main() { while (scanf("%d",&n) , n) { memset (bit,0,sizeof(bit)); memset (ans,0,sizeof(ans)); for (int i=1;i<=n;i++) { scanf("%d%d",&data[i].x,&data[i].y); data[i].x++; //树状数组从1开始 data[i].id=i; xmax=max(xmax,data[i].x); } Deal (); } return 0; }
Poj 3067 Japan
题目链接:http://poj.org/problem?id=3067
题意:有两排城市,这两排之间有一些城市之间有连接的道路,给出所有道路,问有多少道路是相交的
思路:设每一条线为(Ni,Mi),将所有的线按照Mi降序排列,Mi相同的话,按照Ni降序排列,最后只处理Ni
每次统计的时候,从1统计到Ni-1.此时,左边的是比Ni小的,右边是比Ni的相应点(即Mi)大的,所以必与该线段有交点。
需要用__int64来记录答案个数
#include <cstring> #include <algorithm> using namespace std; struct Node { int x,y; }data[1000010]; int bit[1005]; int N,M,K; int lowbit(int x) { return x&(-x); } void Update (int k) { while(k<=N) { bit[k]+=1; k+=lowbit(k); } } int GetSum (int k) { int sum=0; while (k>0) { sum+=bit[k]; k-=lowbit(k); } return sum; } bool cmp (Node a,Node b) { if (a.y==b.y) return a.x>b.x; return a.y>b.y; } int main() { int T; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { scanf("%d%d%d",&N,&M,&K); memset(bit,0,sizeof(bit)); int i; for (i=1;i<=K;i++) scanf("%d%d",&data[i].x,&data[i].y); __int64 ans=0; sort(data+1,data+K+1,cmp); Update (data[1].x); for (i=2;i<=K;i++) { ans+=GetSum(data[i].x-1); Update(data[i].x); } printf("Test case %d: %I64d\n",Cas,ans); } return 0; }
相关文章推荐
- POJ 2352_Stars && POJ-2481 Cows (线段树单点更新+树状数组)
- poj2352+2481 stars+cows 树状数组
- poj 2352 Stars--树状数组
- poj 2352 Stars(线段树||树状数组)
- poj_2481,Cows,树状数组
- POJ 2352 Stars 树状数组
- poj2352~树状数组~线段树尝试失败~
- poj_3067 树状数组
- POJ2352 Stars 树状数组
- POJ_3067_树状数组
- POJ2352 Stars 树状数组
- poj_2352树状数组
- POJ 2481 Cows 树状数组
- POJ 2481:Cows 树状数组
- poj 2352 Stars 树状数组
- poj 2352 hdu 2642 hdu 1556 poj 2155 树状数组
- poj 2481 树状数组
- poj_2481,Cows,树状数组
- poj 2352 树状数组
- poj2481-树状数组的应用