zoukankan      html  css  js  c++  java
  • [洛谷1053] 鬼子进村

    题目背景

    小卡正在新家的客厅中看电视。电视里正在播放放了千八百次依旧重播的《亮剑》,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战。

    题目描述

    描述 县城里有n个用地道相连的房子,第i个只与第i-1和第i+1个相连。这是有m个消息依次传来

    1、消息为D x:鬼子将x号房子摧毁了,地道被堵上。

    2、消息为R :村民们将鬼子上一个摧毁的房子修复了。

    3、消息为Q x:有一名士兵被围堵在x号房子中。

    李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。

    输入输出格式

    输入格式:

    第一行2个整数n,m(n,m<=50000)。

    接下来m行,有如题目所说的三种信息共m条。

    输出格式:

    对于每一个被围堵的士兵,输出该士兵能够到达的房子数。

    输入输出样例

    输入样例#1: 
    7 9
    D 3
    D 6
    D 5
    Q 4
    Q 5
    R
    Q 4
    R
    Q 4
    
    输出样例#1: 
    1
    0
    2
    4
    

    说明

    若士兵被围堵在摧毁了的房子中,那只能等死了。。。。。。

    思路

    一个平衡树,内部储存被破坏的房子,支持添加删除,查询前驱后继即可;

    一个布尔数组,储存每个房子的毁坏情况;

    一个栈,记录毁坏房子的顺序;

    ans如果房子毁坏为0,否则为后继-前驱-1;

    代码实现

     1 #include<cstdio>
     2 const int maxn=5e4+10;
     3 int rt,ts;
     4 int t[maxn];
     5 int f[maxn],s[maxn][2];
     6 void rot(int x){
     7     int y=f[x],z=f[y],l,r;
     8     l=s[y][0]==x?0:1,r=l^1;
     9     if(y!=rt) s[z][s[z][1]==y]=x;
    10     f[x]=z,f[y]=x,f[s[x][r]]=s[x][r]!=0?y:0;
    11     s[y][l]=s[x][r],s[x][r]=y;
    12 }
    13 void splay(int x){
    14     int y,z;
    15     while(x!=rt){
    16         y=f[x],z=f[y];
    17         if(y==rt) rot(x),rt=x;
    18         else{
    19             rot((s[z][0]==y)==(s[y][0]==x)?y:x),rot(x);
    20             if(z==rt) rt=x;
    21         }
    22     }
    23 }
    24 void ins(int k,int x){
    25     int fa=0;
    26     while(k&&t[k]!=x) fa=k,k=s[k][x>t[k]];
    27     k=s[fa][x>t[fa]]=++ts;
    28     t[k]=x,f[k]=fa;
    29     splay(k);
    30 }
    31 void del(int k,int x){
    32     while(t[k]!=x) k=s[k][x>t[k]];
    33     splay(k);
    34     rt=x=s[k][0];
    35     while(s[x][1]) x=s[x][1];
    36     s[x][1]=s[k][1],f[s[k][1]]=x;
    37 }
    38 int in_x(int k,int x,int now){
    39     if(!k) return now;
    40     if(x>t[k]) return in_x(s[k][1],x,t[k]);
    41     else return in_x(s[k][0],x,now);
    42 }
    43 int ax_x(int k,int x,int now){
    44     if(!k) return now;
    45     if(x<t[k]) return ax_x(s[k][0],x,t[k]);
    46     else return ax_x(s[k][1],x,now);
    47 }
    48 int n,m,x;
    49 int q[maxn],top;
    50 bool v[maxn];
    51 char ch[3];
    52 int main(){
    53     scanf("%d%d",&n,&m);
    54     rt=++ts,t[rt]=n+2,ins(rt,1);
    55     while(m--){
    56         scanf("%s",ch);
    57         if(ch[0]=='D'){
    58             scanf("%d",&x);
    59             v[q[++top]=x]=1;
    60             ins(rt,x+1);
    61         }
    62         if(ch[0]=='R'){
    63             v[x=q[top--]]=0;
    64             del(rt,x+1);
    65         }
    66         if(ch[0]=='Q'){
    67             scanf("%d",&x);
    68             if(v[x]) puts("0");
    69             else printf("%d
    ",ax_x(rt,x+1,0)-in_x(rt,x+1,0)-1);
    70         }
    71     }
    72     return 0;
    73 }

    //自己yy的想法T了,就懒得写,直接粘了板子QuQ

  • 相关阅读:
    跟我一起来学ORACLE开发系列之一:CentOS下ORACLE安装篇 老猫
    Oracle中常用的数据字典 老猫
    面试遇到的问题 老猫
    ORACLE删除重复数据 老猫
    fstab修改错了后的解决方案 老猫
    PHP 中使用参数化查询
    安装和配置 WAMP 网页服务
    SkyDrive API 的使用
    PHP 中错误的类型与处理
    JavaScript 中的事件模拟
  • 原文地址:https://www.cnblogs.com/J-william/p/8094246.html
Copyright © 2011-2022 走看看