您的位置:首页 > 其它

Codeforces 12D Ball (树状数组)

2013-01-12 11:05 295 查看
题意:给你N个女人的Beauty,Intelect,richness值,女人之间如果Bi<Bj&&Ii<Ij&&Ri<Rj,那么i女人就会去自杀.....0.0!问总共有多少个女人回去自杀......

思路:对于女人i,想要知道她自不自杀,无非是有没有女人j,使得Bi<Bj&&Ii<Ij&&Ri<Rj。这里用树状数组表示前i个女人中R值的最大值写,由于那三个值小于等于1e9,所以必须离散化。相对其中某个量(这里我按B来排序)升序排序,然后编号,这样生成的树状数组,保证在查询时满足getmax(id+1)中所有的女人的B值比当前女人的要大。于是再按I值降序,这样保证在之后的遍历中,lady[i].i>=lady[i-1].i,再以R值更新树状数组

#include <stdio.h>
#include <algorithm>
#define maxn 500005
using namespace std;
int c[maxn],n,cnt;
inline int lowbit(int x)
{
return x&(-x);
}
void add(int x,int d)
{
while(x>0)
{
if(c[x]<d)
c[x]=d;
x-=lowbit(x);
}
}
int getmax(int x)
{
int s=-1;
for(int i=x; i<=cnt; i+=lowbit(i))
{
if(s<c[i])
s=c[i];
}
return s;
}
struct node
{
int b,i,r;
int id;
} lady[maxn];
bool cmp(node a,node b)
{
return a.b<b.b;
}
bool cmp1(node a,node b)
{
return a.i>b.i;
}
int main()
{
int i,j,ans;
while(scanf("%d",&n)!=EOF)
{
ans=0;
for(i=0; i<n; i++)
scanf("%d",&lady[i].b);
for(i=0; i<n; i++)
scanf("%d",&lady[i].i);
for(i=0; i<n; i++)
scanf("%d",&lady[i].r);
sort(lady,lady+n,cmp);
cnt=1;
lady[0].id=1;
for(i=1; i<n; i++)
{
if(lady[i].b==lady[i-1].b)
lady[i].id=cnt;
else
lady[i].id=++cnt;
}
sort(lady,lady+n,cmp1);
for(i=1; i<=cnt; i++)
c[i]=-1;
for(i=0; i<n;)
{
for(j=i; j<n&&lady[i].i==lady[j].i; j++)
if(getmax(lady[j].id+1)>lady[j].r) ans++;
for(j=i; j<n&&lady[i].i==lady[j].i; j++)
add(lady[j].id,lady[j].r);
i=j;
}
printf("%d\n",ans);
}
return 0;
}
好久没有写过树状数组的题了,网上看了发现可以用树状数组写,才恍然大悟,唉,水平才次了....
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: