Codeforces 12D Ball (树状数组)

来源:互联网 发布:网络舆情管理工作总结 编辑:程序博客网 时间:2024/04/27 22:06

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

原创粉丝点击