• Tunnel Warfare


    hdu1540:http://acm.hdu.edu.cn/showproblem.php?pid=1540

    题意:给你一列村庄,每个村庄给一个标号,1--n,然后毁掉一些村庄,或者重建几个村庄,重建是按照毁掉的反序建的,也就是说,最新建的是最后毁掉的那个村庄。在这些过程中会有一些查询,查询pos这个村庄所在的最长的连续村庄的个数。
    题解:很容易想到用线段树来维护,维护区间的最大左连续和最大右连续值,毁掉就是单点更新操作,同时把毁掉的村庄一次放入队列中,重建的时候只要从队列中取出即可。唯一难的是查询操作。一开始,我没有想到如何查询。最后只好查询了别人的代码。分几种情况, 如果pos在该区间的左连续或者右连续中,直接返回左连续或者右连续的值。如果不在,则需要判断是否在左儿子里面。若在左儿子里面,则需要判断是否在左儿子的右连续中如果在,则需要以右儿子的左端点为查询对象在右子树中 查询,然后把左儿子和右儿子的查询结果
    相加,返回。如果pos在右儿子,同理。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 using namespace std;
     6 struct Node{
     7     int left,right;
     8     int lsum,rsum;
     9 }node[50002<<2];
    10 int ans[10000];
    11 int top;
    12 int n,m;
    13 void build(int l,int r,int idx){//普通的建树 
    14     node[idx].left=l;
    15     node[idx].right=r;
    16     if(l==r){
    17         node[idx].lsum=node[idx].rsum=1;
    18         return;
    19     }
    20     int mid=(l+r)/2;
    21     build(l,mid,idx<<1);
    22     build(mid+1,r,idx<<1|1);
    23     node[idx].lsum=node[idx].rsum=r-l+1;
    24 }
    25 void pushup(int idx){//区间左连续和右连续的维护 
    26     if(node[idx<<1].lsum==node[idx<<1].right-node[idx<<1].left+1)//左连续的处理 
    27         node[idx].lsum=node[idx<<1].lsum+node[idx<<1|1].lsum;
    28      else 
    29         node[idx].lsum=node[idx<<1].lsum;
    30    if(node[idx<<1|1].rsum==node[idx<<1|1].right-node[idx<<1|1].left+1)//右连续的处理 
    31         node[idx].rsum=node[idx<<1].rsum+node[idx<<1|1].rsum;
    32     else
    33         node[idx].rsum=node[idx<<1|1].rsum;
    34 }
    35 void update(int pos,int val,int idx){//单点更新 
    36     if(node[idx].left==node[idx].right){
    37        node[idx].lsum=node[idx].rsum=val;
    38           return;
    39     }
    40     int mid=(node[idx].left+node[idx].right)/2;
    41     if(mid>=pos)update(pos,val,idx<<1);
    42     else update(pos,val,idx<<1|1);
    43       pushup(idx);
    44 }
    45 int query(int pos,int idx){//查询,分情况讨论 
    46      if(pos<=node[idx].left+node[idx].lsum-1)
    47       return node[idx].lsum;
    48      if(pos>=node[idx].right-node[idx].rsum+1)//这里无法保证pos一定在叶子节点的左连续或者右连续中,因为该村庄可能已经被毁 
    49          return node[idx].rsum;
    50           //printf("%d
    ",node[idx].left);
    51      if(node[idx].left==node[idx].right)return node[idx].lsum;//到达叶子节点时候要返回,因为上面的条件无法保证 
    52        int mid=(node[idx].left+node[idx].right)/2;
    53      if(mid>=pos){
    54          if(pos>=node[idx<<1].right-node[idx<<1].rsum+1)
    55             return query(pos,idx<<1)+query(node[idx<<1|1].left,idx<<1|1);
    56            else 
    57              return query(pos,idx<<1);
    58      }
    59      else {
    60          if(pos<=node[idx<<1|1].lsum+node[idx<<1|1].left-1)
    61             return query(pos,idx<<1|1)+query(node[idx<<1].right,idx<<1);
    62           else
    63              return  query(pos,idx<<1|1);
    64      }
    65  }
    66  int main(){
    67      char temp;int data;
    68      while(~scanf("%d%d",&n,&m)){
    69          top=-1;
    70          build(1,n,1);
    71          while(m--){
    72          cin>>temp;
    73          if(temp=='D'){
    74              cin>>data;
    75              ans[++top]=data;
    76              update(data,0,1);
    77          }
    78          else if(temp=='R'){
    79              int tt=ans[top--];
    80              update(tt,1,1);
    81          }
    82          else{
    83              cin>>data;
    84              printf("%d
    ",query(data,1));
    85              }
    86          }
    87      }
    88  }
    View Code
  • 相关阅读:
    文件中的类都不能进行设计,因此未能为该文件显示设计器。设计器检查出文件中有以下类: FormMain --- 未能加载基类“WinForm.Win.FormsBase.FormMainBase”。请确保已引用该程序集并已生成所有项目
    Xcopy命令参数使用介绍
    c#生成方案里预生成拷贝文件
    visual studio 2010 出现问题,不能设置断点调试了,一运行就未响应,然后程序退出
    开启Visual Studio 2013时,出现Microsoft.VisualStudio.Web.PasteJson.JsonPackage无法载入的可能解決方案
    Java开发知识之XML文档使用,解析
    JAVA开发知识之Java的线程
    git版本控制工具的使用
    Java开发知识之Java的正则表达式
    PC逆向之代码还原技术,第一讲基本数据类型在内存中的表现形式.浮点,指针寻址公式
  • 原文地址:https://www.cnblogs.com/chujian123/p/3436176.html
Copyright © 2020-2023  润新知