hdu5372(树状数组)

来源:互联网 发布:简单粗暴网络用语 编辑:程序博客网 时间:2024/06/09 16:24
开始看这题时以为是线段树区间更新,误以为和poj2528差不多,然后上手打了。。。到末尾时发现有个点不一样,那就是删除,还要恢复到之前的状态,这个不会了。又从树状数组入手,发现用树状数组很简单。这题的主要思想,求得左端点大于等于左端点的线段的个数,然后再求得右端点大于该线段右端点的个数,然后两数相减得出答案,用两个树状数组维护即得到答案
#include <iostream>#include<stdio.h>#include<algorithm>#include<math.h>#include<cstring>#define mem(a) memset(a,0,sizeof(a))using namespace std;const int M=2*1e5+20;typedef struct{    int op,id;}PP;PP p[M];typedef struct{    int st,End,id;}OP;OP ad[M];typedef struct{    int num,id;}Trans;Trans tr[2*M];bool cmp(const Trans&a,const Trans&b){    return a.num<b.num;}int del[M];int start[M*2],eend[2*M];void add(int n,int x,int *s){    while(n<2*M)    {        s[n]+=x;        n+=n&(-n);    }}int getsum(int n,int *s){    int sum=0;    while(n>=1)    {        sum+=s[n];        n-=n&(-n);    }    return sum;}int main(){    int n,T=1;    while(~scanf("%d",&n))    {        memset(start,0,sizeof(start));        memset(eend,0,sizeof(eend));        int i, t=0,s=1,ff,b;        for(i=1;i<=n;i++)        {            scanf("%d%d",&ff,&b);            if(ff==0)            {                ++t;                p[i].id=t;                p[i].op=0;                tr[2*t-1].num=b;                tr[2*t-1].id=t;                tr[2*t].num=b+t;                tr[2*t].id=-1*t;            }            else            {                p[i].id=s;                p[i].op=1;                del[s++]=b;            }        }        sort(tr+1,tr+1+2*t,cmp);        int tt=1,temp=tr[1].num;        for(i=1;i<=t*2;i++)        {            if(temp<tr[i].num)            {                tt++;                temp=tr[i].num;            }            if(tr[i].id>0)            {                ad[tr[i].id].st=tt;                ad[tr[i].id].id=tr[i].id;            }            else            {                ad[tr[i].id*(-1)].End=tt;                ad[tr[i].id*(-1)].id=tr[i].id*(-1);            }        }        printf("Case #%d:\n",T++);        for(int i=1;i<=n;i++)        {            int d=p[i].id;            if(p[i].op==0)            {                int st=ad[d].st,ed=ad[d].End,sum1=0,sum2=0;                add(st,1,start);                add(ed,1,eend);                sum1=getsum(2*M-1,start)-getsum(st-1,start);                sum2=getsum(2*M-1,eend)-getsum(ed,eend);                printf("%d\n",sum1-1-sum2);            }            else            {                int s=del[d];                int st=ad[s].st,ed=ad[s].End;                add(st,-1,start);                add(ed,-1,eend);            }        }    }    return 0;}

0 0
原创粉丝点击