• HDU1540 Tunnel Warfare(线段树区间更新)


    描述

    传送门:我是传送门

    During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected with two neighboring ones.

    Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!

    输入

    The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of villages and events. Each of the next m lines describes an event.

    There are three different events described in different format shown below:

    D x: The x-th village was destroyed.

    Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.

    R: The village destroyed last was rebuilt.

    输出

    Output the answer to each of the Army commanders’ request in order on a separate line.

    样例

    输入

    7 9
    D 3
    D 6
    D 5
    Q 4
    Q 5
    R
    Q 4
    R
    Q 4

    输出

    1
    0
    2
    4

    题目大意

    有三种操作

    D x 破坏掉x点

    Q x 查询x点左右联通的点数(最长的连续区间)

    R 恢复上一个破坏掉的点

    思路

    由于操作’R’的存在,需要将操作D依次存下来,或者单独一个变量来记录上一个破坏的点,在这里我选择用数组存。

    每次都新建一棵线段树,线段树需要保存的值除了左右端点外要加上三个最值。即:区间内左端连续的最长的区间、区间内右端连续的最长区间、区间内连续的最长的区间

    以上这些在开始写之前还是能想到的,但是在处理区间合并的时候有些不太会处理,因此参考(抄)了bin神的代码,感觉bin神在合并的时候处理的非常巧妙。

    如果对于更新与查询操作不是很理解,可以自己在纸上试一试,对整个过程会更清晰

    代码

      1 /*
      2  *==========================================================
      3  *
      4  *       Filename:  I.cpp
      5  *
      6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=1540
      7  *
      8  *        Version:  1.0
      9  *        Created:  2018/09/15 12时22分38秒
     10  *       Revision:  none
     11  *       Compiler:  g++
     12  *
     13  *         Author:  杜宁元 (https://duny31030.top/), duny31030@126.com
     14  *   Organization:  QLU_浪在ACM
     15  *
     16  *==========================================================
     17  */
     18 #include <bits/stdc++.h>
     19 using namespace std;
     20 bool Finish_read;
     21 template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
     22 template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
     23 template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('
    ');}
     24 template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
     25 #define clr(a, x) memset(a, x, sizeof(a))
     26 #define rep(i,a,n) for(int i=a;i<=n;i++)
     27 #define pre(i,a,n) for(int i=n;i>=a;i--)
     28 #define ll long long
     29 #define max3(a,b,c) fmax(a,fmax(b,c))
     30 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     31 const double eps = 1e-6;
     32 const int INF = 0x3f3f3f3f;
     33 const int mod = 1e9 + 7;
     34 const int N = 5e4+100;
     35 int tot = 0;
     36 int a[N];
     37 
     38 struct node
     39 {
     40     int l,r;
     41     int le,ri,mi;
     42 }tree[N<<2];
     43 // tree[i].le 区间左端点开始的最大连续个数
     44 // tree[i].ri 区间右端点开始的最大连续个数
     45 // tree[i].mi 区间最大的连续点的个数
     46 
     47 
     48 void Build(int i,int l,int r)
     49 {
     50     tree[i].l = l;
     51     tree[i].r = r;
     52     tree[i].le = tree[i].ri = tree[i].mi = r-l+1;
     53     if(r == l)
     54         return ;
     55     int mid = (l+r)>>1;
     56     Build(i<<1,l,mid);
     57     Build(i<<1|1,mid+1,r);
     58 }
     59 
     60 // val = 1 恢复这个点
     61 // val = 0 破坏这个点
     62 void Update(int i,int t,int val)
     63 {
     64     if(tree[i].l == tree[i].r)
     65     {
     66         if(val == 1)
     67             tree[i].le = tree[i].ri = tree[i].mi = 1;
     68         else 
     69             tree[i].le = tree[i].ri = tree[i].mi = 0;
     70         return ;
     71     }
     72     int mid = (tree[i].l+tree[i].r)>>1;
     73     if(t <= mid)
     74         Update(i<<1,t,val);
     75     else 
     76         Update(i<<1|1,t,val);
     77     tree[i].le = tree[i<<1].le;
     78     tree[i].ri = tree[i<<1|1].ri;
     79     tree[i].mi = max(tree[i<<1].mi,tree[i<<1|1].mi);
     80     tree[i].mi = max(tree[i].mi,tree[i<<1].ri+tree[i<<1|1].le);
     81 
     82     if(tree[i<<1].le == tree[i<<1].r-tree[i<<1].l+1)
     83         tree[i].le += tree[i<<1|1].le;
     84     if(tree[i<<1|1].ri == tree[i<<1|1].r-tree[i<<1|1].l+1)
     85         tree[i].ri += tree[i<<1].ri;
     86 }
     87 
     88 int Query(int i,int t)
     89 {
     90     if(tree[i].l == tree[i].r || tree[i].mi == 0 || tree[i].mi == tree[i].r-tree[i].l+1)
     91         return tree[i].mi;
     92     int mid = (tree[i].l+tree[i].r)>>1;
     93     if(t <= mid)
     94     {
     95         if(t >= tree[i<<1].r-tree[i<<1].ri+1)
     96             return Query(i<<1,t)+Query(i<<1|1,mid+1);
     97         else 
     98             return Query(i<<1,t);
     99     }
    100     else 
    101     {
    102         if(t <= tree[i<<1|1].l+tree[i<<1|1].le-1)
    103             return Query(i<<1|1,t)+Query(i<<1,mid);
    104         else 
    105             return Query(i<<1|1,t);
    106     }
    107 }
    108 
    109 int main()
    110 {
    111     ios
    112 #ifdef ONLINE_JUDGE 
    113 #else 
    114         freopen("in.txt","r",stdin);
    115     // freopen("out.txt","w",stdout); 
    116 #endif
    117     int n,m,x;
    118     char op[10];
    119     while(scanf("%d %d",&n,&m) != EOF)
    120     {
    121         tot = 0;
    122         Build(1,1,n);
    123         rep(i,1,m)
    124         {
    125             // cin >> op;
    126             scanf("%s",op);
    127             if(op[0] == 'D')
    128             {
    129                 scanf("%d",&x);
    130                 a[tot++] = x;
    131                 Update(1,x,0);
    132             }
    133             else 
    134             {
    135                 if(op[0] == 'R')
    136                 {   
    137                     x = a[--tot];
    138                     Update(1,x,1);
    139                 }
    140                 else 
    141                 {
    142                     scanf("%d",&x);
    143                     printf("%d
    ",Query(1,x));
    144                 }
    145             }
    146         }
    147     }
    148     fclose(stdin);
    149     // fclose(stdout);
    150     return 0;
    151 }
  • 相关阅读:
    Python正课38 —— 有参装饰器
    Python正课37 —— 无参装饰器
    Python正课36 —— 闭包函数
    Python正课35 —— 函数对象与函数嵌套
    Python正课34 —— Global与Nonlocal
    Python正课33 —— 名称空间 与 作用域 介绍
    vue中wowjs的使用
    js得到时间戳(10位数)
    腾讯地图使用中,出现了“鉴权失败,请传入正确的key”
    js数组操作大全
  • 原文地址:https://www.cnblogs.com/duny31030/p/14305005.html
Copyright © 2020-2023  润新知