poj 2892 Tunnel Warfare

http://poj.org/problem?id=2892

此代码在POJ上能过 在hdu上过不了

题目大意:

n个村庄相连  三种操作

D 摧毁一个村庄

Q 查询包括此村庄在内和此村庄直接和间接相连的村庄数

R 修复上一个被摧毁的村庄

Ttree 写的很烂呀

思路:

将摧毁的村庄插入二叉树中

每次询问 就查找它左边和右边最近被摧毁的村庄 就可以知道答案了

修复一个村庄 就把它在树中删除

代码及其注释:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<cmath>

#include<queue>

#include<algorithm>

#include<stack>



using namespace std;



const int N=50010;

struct node

{

    int k;

    int l,r,f;

}mem[N];

int destroy[N];//是否被摧毁

int treehead,n;//头结点 和村庄个数

stack<int>str;//保存被摧毁的村庄

void RightTurn(int i)//右转

{

    int f=mem[i].f;

    int l=mem[i].l;

    if(f==-1)

    {

        mem[l].f=-1;

        treehead=l;

    }else

    {

        if(mem[f].l==i)

        mem[f].l=l;

        else

        mem[f].r=l;

        mem[l].f=f;

    }

    mem[i].l=mem[l].r;

    if(mem[l].r!=-1)

    mem[mem[l].r].f=i;

    mem[l].r=i;

    mem[i].f=l;

}

void LeftTurn(int i)//左转

{

    int f=mem[i].f;

    int r=mem[i].r;

    if(f==-1)

    {

        mem[r].f=-1;



        treehead=r;

    }else

    {

        if(mem[f].l==i)

        mem[f].l=r;

        else

        mem[f].r=r;

        mem[r].f=f;

    }

    mem[i].r=mem[r].l;

    if(mem[r].l!=-1)

    mem[mem[r].l].f=i;

    mem[r].l=i;

    mem[i].f=r;

}

void insert(int i,int k)//插入

{

    if(k<i)

    {

        if(mem[i].l!=-1)

        {

            insert(mem[i].l,k);

            if(mem[mem[i].l].k<mem[i].k)

            {

                RightTurn(i);

            }

        }else

        {

            mem[i].l=k;

            mem[k].f=i;

        }

    }else

    {

        if(mem[i].r!=-1)

        {

            insert(mem[i].r,k);

            if(mem[mem[i].r].k<mem[i].k)

            {

                LeftTurn(i);

            }

        }else

        {

            mem[i].r=k;

            mem[k].f=i;

        }

    }

}

void dele(int i,int k)//删除

{

    if(i<k)

    {

        dele(mem[i].r,k);

    }else if(i>k)

    {

        dele(mem[i].l,k);

    }else

    {

        int x=i;

        while(mem[x].l!=-1||mem[x].r!=-1)

        {

            if(mem[x].l!=-1)

            {

                RightTurn(x);

            }else

            {

                LeftTurn(x);

            }

        }

        if(mem[x].f==-1)

        {

            treehead=-1;return;

        }

        if(mem[mem[x].f].l==x)

        mem[mem[x].f].l=-1;

        if(mem[mem[x].f].r==x)

        mem[mem[x].f].r=-1;

    }

}

void LeastLeft(int i,int k,int *L)//求最近左被摧毁村庄

{

    if(i==-1)

    {

        return;

    }

    if(k<=i)

    {

        LeastLeft(mem[i].l,k,L);

    }else if(k>i)

    {

        *L=max(*L,i);

        LeastLeft(mem[i].r,k,L);

    }



}

void LeastRight(int i,int k,int *R)//求最近右被摧毁村庄

{

    if(i==-1)

    {

        return;

    }

    if(k<i)

    {

        *R=min(*R,i);

        LeastRight(mem[i].l,k,R);

    }else if(k>=i)

    {

        LeastRight(mem[i].r,k,R);

    }

}

void begin()//初始化一些内容

{

   while(!str.empty())

   str.pop();

   memset(destroy,0,sizeof(destroy));

   treehead=-1;

}

int main()

{

   int m;

   while(scanf("%d %d",&n,&m)!=EOF)

   {

       begin();

       char c;

       int i;

       for(int k=1;k<=m;++k)

       {

           getchar();

           scanf("%c",&c);

           if(c=='D')

           {

               scanf("%d",&i);

               mem[i].l=mem[i].r=-1;

               mem[i].k=k;

               if(treehead==-1)//如果树是空的

               {

                   treehead=i;

                   mem[i].f=-1;

               }else

               {

                   insert(treehead,i);//否则 插入

               }

               str.push(i);

               ++destroy[i];//记录

           }else if(c=='Q')

           {

               int ans,L,R;

               scanf("%d",&i);

               if(destroy[i]>0)//特殊情况

               {

                  ans=0;

               }else

               {

                   L=0;

                   LeastLeft(treehead,i,&L);

                   R=n+1;

                   LeastRight(treehead,i,&R);

                   ans=R-L-1;

               }

               printf("%d\n",ans);



           }else

           {

               if(str.empty())

               continue;

               dele(treehead,str.top());//删点 并记录

               --destroy[str.top()];

               str.pop();

           }

       }

   }

   return 0;

}

 

你可能感兴趣的:(poj)