题目链接地址:
PKU 2481:http://poj.org/problem?id=2481
PKU 2352:http://poj.org/problem?id=2352
HDU 1541:http://acm.hdu.edu.cn/showproblem.php?pid=1541
其中PKU 2352和HDU 1541是一样的。 = =、、买一送一。。
************************************************************************************************************************************************************************************
方法:树状数组+排序。
PKU 2481的题意大概就是问每个点,在它的左上方有多少个点,另外两道的题意就是问每个点,在它的左下方有多少个点。(按数学书上的坐标)
PKU 2481的y不是下降的。所以要把它排序成下降的。然后对x进行树状数组算出,需要注意的就是相同点的时候和x要++。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define low_bit(k) k&-k;
using namespace std;
int n,mx,my;
int tol[100100];//用于树状数组
int val[100100];//每个点的结果(左上方的点的个数)
struct Node{
int x,y;
int d;
}dq[100100];
int cmp(Node a,Node b){//排序不解释
if(a.y==b.y) return a.x<b.x;
return a.y>b.y;
}
int _cmp(Node a,Node b){
return a.d<b.d;
}
void add(int x){
while(x<=mx){
tol[x]+=1;
x+=low_bit(x);
}
}
int sum(int x){
int cnt=0;
while(x) cnt+=tol[x],x-=low_bit(x);
return cnt;
}
int main(){
int i,tot;
while(scanf("%d",&n),n){
memset(tol,0,sizeof(tol));
memset(val,0,sizeof(val));
for(i=1,mx=0,my=0;i<=n;i++){
scanf("%d%d",&dq[i].x,&dq[i].y);
dq[i].x++,dq[i].y++;
dq[i].d=i;
mx<dq[i].x?mx=dq[i].x:0;
}
sort(dq+1,dq+n+1,cmp);
val[dq[1].d]=sum(dq[1].x);
add(dq[1].x);
for(i=2;i<=n;i++){
if(dq[i].y==dq[i-1].y&&dq[i].x==dq[i-1].x){//如果有相同点的时候
//排序后相邻了,所以直接等于前一个,但要add();
val[dq[i].d]=val[dq[i-1].d];
add(dq[i].x);
continue;
}
val[dq[i].d]=sum(dq[i].x);
add(dq[i].x);
}
for(i=1;i<n;i++) printf("%d ",val[i]);
printf("%d\n",val[n]);
}
return 0;
}
PKU 2352和HDU 1541是同一题,y是上升序列,所以直接对x用树状数组解决,需要注意的就是x要++,我没++的时候是TLE。
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define low_bit(k) k&-k;
using namespace std;
int n;
int val[15001];
int tol[32003];
void addx(int x){
while(x<=32002){
tol[x]++;
x+=low_bit(x);
}
}
int sumx(int x){
int cnt=0;
while(x){
cnt+=tol[x];
x-=low_bit(x);
}
return cnt;
}
int main(){
int i,tot,etot,x,y;
while(~scanf("%d",&n)){
memset(val,0,sizeof(val));
memset(tol,0,sizeof(tol));
for(i=1;i<=n;i++){
scanf("%d%d",&x,&y);
val[sumx(++x)]++;
addx(x);
}
for(i=0;i<n;i++) printf("%d\n",val[i]);
}
return 0;
}