PKU 2481 Cows & PKU 2352 Stars & HDU 1541 Stars

题目链接地址:

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;
}


 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值