POJ 2481 Cows(树状数组)

当前树状数组练习最后一道题。

借此写一下常用模型。Stars Japan 等线段树,树状数组的题目除了非常裸的模版题目(敌兵布阵)。都是将几个属性值按照次序排列。

完后,所求即是线性区间个数问题。看规模很少有二维的,利用序将多维降维。(这题刚开始将E-S也当作一个属性在考虑.....失误)

这道题也是,对于S,E的次序调整好,将两个变量(E-S的这个其实是区间长度包含意思,本身并不影响)换好次序。按照S升,E降排后,前面的元素不可能比后面的元素weak

这样每次统计线段中比自身小的再减去就OK

这道题还有就是区间重合的计算,重合的区间 Strong相同。


#include<cstdio>
#include<string> 
#include<string.h>
#include<iostream>
#include<algorithm> 
#include<map>
#include<iterator>
using namespace std;
#define N 100+100000
int n,m;
int tt[N];
int d[N];
struct P
{
	int a,b,c;
}p[N*N];
bool cmp(const struct P &a,const struct P &b)
{
	if(a.a==b.a)
		return a.b>b.b;
	return a.a<b.a;
}

int lowbit(int x){return -x&x;}
void update(int r)
{
	int i,j;
	for(i=r;i<N;i+=lowbit(i))
		tt[i]+=1;

}
int getsum(int r)
{
	int i,j;
	int ans=0;
	for(i=r;i>0;i-=lowbit(i))
		ans+=tt[i];
	return ans;
}

int main()
{
	int i;
	int T;

	//freopen("in.txt","r",stdin);
	while(scanf("%d",&n) && n)
	{
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&p[i].a,&p[i].b);
			p[i].a++;p[i].b++;
			p[i].c=i;
		}

		memset(tt,0,sizeof(tt));
		memset(d,0,sizeof(d));
		sort(p,p+n,cmp);
		for(i=0;i<n;i++)
		{		
			if(i==0) 
			{
				d[p[i].c]=0;update(p[i].b);
				continue;
			}

			if(p[i].b==p[i-1].b && p[i].a==p[i-1].a)
				d[p[i].c]=d[p[i-1].c];
			else
				d[p[i].c]=getsum(N-1)-getsum(p[i].b-1);

			update(p[i].b);
		}
		for(i=0;i<n;i++)
			if(i==n-1)	printf("%d\n",d[i]);
			else printf("%d ",d[i]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值