CDOJ 数据结构训练H 树状数组离散化

来源:互联网 发布:钢铁侠反应堆淘宝 编辑:程序博客网 时间:2024/06/07 20:31
#include <map>#include <set>#include <list>#include <cmath>#include<cctype>#include <ctime>#include <deque>#include <stack>#include <queue>#include <cstdio>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define PI 3.1415926535897932626#define SYM 300000006#define MAXN 600010using namespace std;int gcd(int a, int b){return a % b == 0 ? b : gcd(b, a % b);}struct node{    char input[20];//离散化处理    LL trans;//更改值    LL index;//下标    LL origin;//原值    friend bool operator <(const node &a,const node &b)    {        return a.origin<b.origin;//降序处理,不是数字的处理为0;    }}src[600010];LL res[600010];LL N,kase,num;LL C[600010];int cmp(const node &a,const node &b){    return a.index<b.index;}void show (){    for (LL i=0;i<N-1;i++)        printf("%lld %lld %lld\n",src[i].origin,src[i].trans,src[i].index);}void init()//离散化处理{    memset(C,0,sizeof(C));    N=0;kase=0;num=0;    while(scanf("%s",src[N++].input)!=EOF);//读入数据    for (LL i=0;i<N;i++)//每个结构体处理为数字    {        if (src[i].input[0]=='#') {src[i].origin=SYM;}        else        {            LL x=0,tot=0;            while (isdigit(src[i].input[tot]))            {                x=x*10+src[i].input[tot]-'0';                tot++;            }            src[i].origin=x;            num++;//记录出现数字的数量        }        src[i].index=i;    }    sort(src,src+N-1);    LL cnt=1;    src[0].trans=cnt;    res[cnt]=src[0].origin;    for (LL i=1;i<num-1;i++)//遍历全部是数字的集合,进行离散化    {        if (src[i].origin==src[i-1].origin) {src[i].trans=cnt;}        else        {            src[i].trans=++cnt;            res[cnt]=src[i].origin;        }    }    sort(src,src+N-1,cmp);}inline int Find(LL a){    LL  ans,pos=0,sum=0;    LL bit=1<<21;    while (bit>MAXN) bit>>=1;    while (bit)    {        if (sum+C[pos+bit]<a)        {            pos+=bit;            sum+=C[pos];        }        else        {            ans=pos+bit;        }        bit>>=1;    }    return ans;}inline int read(int pos){    int ans=0;    while (pos>0)    {        ans+=C[pos];        pos-=pos&(-pos);    }    return ans;}inline void update(int pos,int val){    //printf("%d\n",pos);    while (pos<=MAXN)    {        C[pos]+=val;        pos+=pos&(-pos);    }}void slove(){    init();//读入数据    LL cur=0;    for (LL i=0;i<N-1;i++)    {        if (src[i].input[0]!='#')//数字,插入        {            update(src[i].trans,1);            cur++;        }        else        {   LL ans;            if (cur%2==0)                 ans=Find(cur/2+1);            else                ans=Find((cur+1)/2);              printf("%lld\n",res[ans]);              update(ans,-1);              cur--;        }    }}int main(){    //freopen("sample.txt","r",stdin);    slove();    return 0;}

0 0