码迷,mamicode.com
首页 > 其他好文 > 详细

线段树 - 区间合并

时间:2017-10-14 01:45:56      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:number   imm   end   cep   china   self   content   pac   against   

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!

InputThe 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.
OutputOutput the answer to each of the Army commanders’ request in order on a separate line.
Sample Input
7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
Sample Output
1
0
2
4


题意 : 有一排村庄 , D 表示毁掉此村庄 , R 表示重建最后一个被毁掉的村庄 , Q 表示查询所输入的村庄与多少村庄相连, 要包括他本身 。

思路 :
  此类题目属于线段树里的区间合并 , 问最多有多少相连的区间 , 其实他与普通的单点查询差不多 ,但是会在结构体中多存三个量 , lm, rm, mm 分别表示当前区间从最左边数的最大连续长度 , 从右边数的最大连续长度 , 当前区间的最大连续长度 。
其中 lm, rm 的作用是判断 是否要查询的点的另一侧范围在继续查找 , mm 的作用则是当当前区间到底 , 或是所要查找的点就在这个区间 为 空或为满的情况 。

代码示例 :
  
/*
 * Author:  ry 
 * Created Time:  2017/10/13 22:27:56
 * File Name: 1.cpp
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <time.h>
using namespace std;
const int eps = 5e4+5;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define ll long long
#define lson l, m, k<<1
#define rson m+1, r, k<<1|1

stack<int>s;
struct node
{
    int l, r;
    int lm, rm, mm;
}tree[eps<<2];
int ff, ans;

void build(int l, int r, int k){
    tree[k].l = l;
    tree[k].r = r;
    tree[k].lm = tree[k].rm = tree[k].mm = (r - l + 1);
    if (l == r){
        return;
    }
    int m = (tree[k].l + tree[k].r) >> 1;
    build(lson);
    build(rson);    
}

void update(int l, int r, int k, int pt){
    if (l == r){
        if (!pt) {
            tree[k].lm = tree[k].rm = tree[k].mm = 0;
        }
        else tree[k].lm = tree[k].rm = tree[k].mm = 1;
        return;
    }
    int m = (tree[k].l + tree[k].r) >> 1;
    if (ff <= m) update(lson, pt);
    else update(rson, pt);
    tree[k].lm = tree[k<<1].lm;
    tree[k].rm = tree[k<<1|1].rm;
    tree[k].mm = tree[k<<1].rm + tree[k<<1|1].lm;
    if (tree[k<<1].lm == (tree[k<<1].r - tree[k<<1].l + 1)) 
        tree[k].lm = tree[k<<1].lm + tree[k<<1|1].lm;
    if (tree[k<<1|1].rm == (tree[k<<1|1].r - tree[k<<1|1].l + 1))
        tree[k].rm = tree[k<<1|1].rm + tree[k<<1].rm;
    //tree[k].mm = max(max(tree[k<<1].mm, tree[k<<1|1].mm), tree[k<<1].rm + tree[k<<1|1].lm);    
}

void query(int l, int r, int k, int key){
    if (l == r || tree[k].mm == 0 || tree[k].mm == (r - l + 1)){
        ans += tree[k].mm;
        return;
    }
    int m = (tree[k].l + tree[k].r) >> 1;
    if (key <= m){
        int pt = tree[k<<1].r - tree[k<<1].rm + 1;
        if (key >= pt){
            query(lson, key);
            query(rson, m+1);
        }
        else query(lson, key);
    }
    else {
        int pt = tree[k<<1|1].l + tree[k<<1|1].lm - 1;
        if (key <= pt){
            query(rson, key);
            query(lson, m);
        }
        else query(rson, key);
    }
}

int main() {
    int n, m;
    char ch[5];
    
    while (~scanf("%d%d", &n, &m)){
        while (!s.empty()){
            s.pop();
        }
        //cin >> n >> m;
        build(1, n, 1);
        while (m--){
            scanf("%s", ch);
            if (ch[0] == ‘D‘) {
                scanf("%d", &ff);
                s.push(ff);
               
                update(1, n, 1, 0);            
            }
            else if (ch[0] == ‘Q‘){
                scanf("%d", &ff);
                ans = 0;
                query(1, n, 1, ff);
                printf("%d\n", ans);
            }      
            else {
                ff = s.top();
                s.pop();
                update(1, n, 1, 1);
            }  
        }
    }

    return 0;
}

 

线段树 - 区间合并

标签:number   imm   end   cep   china   self   content   pac   against   

原文地址:http://www.cnblogs.com/ccut-ry/p/7664211.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!