Codeforces 12D Ball (树状数组)

题意:给你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;
}
好久没有写过树状数组的题了,网上看了发现可以用树状数组写,才恍然大悟,唉,水平才次了....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值