• 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;
    }
  • 相关阅读:
    vuejs开发环境搭建
    贝塞尔曲线(cubic bezier)
    解决安装mysql的”A Windows service with the name MySQL already exists.“问题
    display:inline-block的间隙问题和解决办法
    限制两行显示,超出部分省略号
    border-radius四个值的问题
    PHP环境搭建
    CSS3属性box-sizing
    -webkit-tap-highlight-color
    gdb命令
  • 原文地址:https://www.cnblogs.com/liulangye/p/2592365.html
Copyright © 2020-2023  润新知