poj2892(treap)

来源:互联网 发布:数据库发展方向 编辑:程序博客网 时间:2024/06/06 16:25

我用的是treap操作的
每一次把被摧毁的村庄放进treap中,然后找到查询点的前驱和后继就是该联通块的起始点前一个和终止点后一个,之后每个联通块中村庄的个数也就知道了,每次修复时将这个村庄从treap中删除即可。

#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;int n,m;int s,t,sz,root;int d[50005];struct Tree{    int l,r;    int num,rnd;}tree[50005];void lturn(int &t){    int k=tree[t].r;    tree[t].r=tree[k].l;    tree[k].l=t;    t=k;}void rturn(int &t){    int k=tree[t].l;    tree[t].l=tree[k].r;    tree[k].r=t;    t=k;}void del(int &w,int x){    if(tree[w].num==x)    {        if(tree[w].l*tree[w].r==0) w=tree[w].l+tree[w].r;        else if(tree[tree[w].l].rnd<tree[tree[w].r].rnd)        {            rturn(w);            del(w,x);        }        else if(tree[tree[w].l].rnd>=tree[tree[w].r].rnd)        {            lturn(w);            del(w,x);        }        return;    }    else if(tree[w].num<x) del(tree[w].r,x);    else del(tree[w].l,x);}void find(int &w,int x){    if(w==0) return;    if(tree[w].num>=x && tree[w].num<t) t=tree[w].num;    if(tree[w].num<=x && tree[w].num>s) s=tree[w].num;    if(tree[w].num<x) find(tree[w].r,x);    else find(tree[w].l,x);}void insert(int &w,int x){    if(w==0)    {        sz++;        w=sz;        tree[w].num=x;        tree[w].rnd=rand();        return;    }    if(tree[w].num<x)    {        insert(tree[w].r,x);        if(tree[tree[w].r].rnd<tree[w].rnd) lturn(w);    }    if(tree[w].num>x)    {        insert(tree[w].l,x);        if(tree[tree[w].l].rnd<tree[w].rnd) rturn(w);    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1,j=0;i<=m;i++)    {        char c;        int a;        getchar();        scanf("%c",&c);        if(c=='D')        {            scanf("%d",&a);            insert(root,a);            j++;            d[j]=a;        }        if(c=='Q')        {            scanf("%d",&a);            s=0;t=n+1;            find(root,a);            if(s==a&&t==a) printf("0\n");            else printf("%d\n",t-s-1);        }        if(c=='R')        {            del(root,d[j]);            j--;        }    }    return 0;}