HDU 1540 Tunnel Warfare 平衡树 / 线段树:单点更新,区间合并

Tunnel Warfare

                                 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Problem Description

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!

Input

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

Output 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

Source

POJ Monthly

题解:区间合并基础题

//1085422276
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#include<bitset>
#include<set>
#include<vector>
#include<stack>
///#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define memfy(a) memset(a,-1,sizeof(a))
#define TS printf("111111\n");
#define FOR(i,a,b) for( int i=a;i<=b;i++)
#define FORJ(i,a,b) for(int i=a;i>=b;i--)
#define READ(a,b) scanf("%d%d",&a,&b)
#define mod 530600414
#define eps 0.0000000001
#define inf 1000000000.0
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)
    {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
//****************************************

#define maxn 500000+5
struct ss
{
    int l,r,L,R,v;
}tr[maxn];
int n,m,lflag,rflag;
void pushup(int k)
{
    if(tr[k<<1].L+tr[k<<1|1].R==(tr[k].r-tr[k].l+1))
    {
        tr[k].L=tr[k].R=(tr[k].r-tr[k].l+1);
    }
    else {
        if(tr[k<<1].L>=(tr[k<<1].r-tr[k<<1].l+1))
            tr[k].L=tr[k<<1].L+tr[k<<1|1].L;
        else tr[k].L=tr[k<<1].L;
        if(tr[k<<1|1].R>=tr[k<<1|1].r-tr[k<<1|1].l+1)
            tr[k].R=tr[k<<1|1].R+tr[k<<1].R;
        else tr[k].R=tr[k<<1|1].R;
    }
}
void build(int k,int s,int t)
{
    tr[k].l=s;
    tr[k].r=t;
    tr[k].L=tr[k].R=t-s+1;
    if(s==t)
    {
        return ;
    }
    int mid=(s+t)>>1;
    build(k<<1,s,mid);
    build(k<<1|1,mid+1,t);
}
void update(int k,int x,int c)
{
    if(tr[k].l==x&&tr[k].r==x)
    {
        tr[k].L=tr[k].R=c;return ;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)update(k<<1,x,c);
    else update(k<<1|1,x,c);
    pushup(k);
}
int ask(int k,int x)
{
    if(tr[k].l==tr[k].r&&tr[k].l==x)
    {
        if(tr[k].L)rflag=lflag=1;
        return tr[k].L;
    }
    int mid=(tr[k].l+tr[k].r)>>1;
    int A=0,B=0;
    if(x<=mid)
    {
        A=ask(k<<1,x);
    }
    else {
         B=ask(k<<1|1,x);
    }
    int ans=A+B;
     if(A && rflag)
     {
         ans+=tr[k<<1|1].L;
         if(tr[k<<1|1].L<tr[k<<1|1].r-tr[k<<1|1].l+1)
            rflag=0;
     }
     if(B && lflag)
     {
         ans+=tr[k<<1].R;
         if(tr[k<<1].R<tr[k<<1].r-tr[k<<1].l+1)
            lflag=0;
     }
     return ans;
}
int main()
{
  char ch[321];
  int x;

    while(scanf("%d%d",&n,&m)!=EOF)
    {
        stack<int >q;
        int last=0;
        build(1,1,n);
        FOR(i,1,m)
        {
            scanf("%s",ch);
            if(ch[0]==‘D‘)
            {cin>>x;
            q.push(x);
                update(1,x,0);
            }
            else if(ch[0]==‘Q‘)
            {
                cin>>x;
                rflag=lflag=0;
               cout<<ask(1,x)<<endl;
            }
            else {
                last=q.top();
                q.pop();
                update(1,last,1);
            }
        }
    }
    return 0;
}

代码

补个 treap写法

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
struct data{
    int l,r,v,size,rnd,w;
}tr[5200005];
int n,size,root,ans;
int last[5000000];
void update(int k)//更新结点信息
{
    tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w;
}
void rturn(int &k)
{
    int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k;
    tr[t].size=tr[k].size;update(k);k=t;
}
void lturn(int &k)
{
    int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k;
    tr[t].size=tr[k].size;update(k);k=t;
}
void insert(int &k,int x)
{
    if(k==0)
    {
        size++;k=size;
        tr[k].size=tr[k].w=1;tr[k].v=x;tr[k].rnd=rand();
        return;
    }
    tr[k].size++;
    if(tr[k].v==x)tr[k].w++;
    else if(x>tr[k].v)
    {
        insert(tr[k].r,x);
        if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k);
    }
    else
    {
        insert(tr[k].l,x);
        if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k);
    }
}
void del(int &k,int x)
{
    if(k==0)return;
    if(tr[k].v==x)
    {
        if(tr[k].w>1)
        {
            tr[k].w--;tr[k].size--;return;
        }
        if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;
        else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd)
            rturn(k),del(k,x);
        else lturn(k),del(k,x);
    }
    else if(x>tr[k].v)
        tr[k].size--,del(tr[k].r,x);
    else tr[k].size--,del(tr[k].l,x);
}

int query_rank(int k,int x)
{
    if(k==0)return 0;
    if(tr[k].v==x)return tr[tr[k].l].size+1;
    else if(x>tr[k].v)
        return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x);
    else return query_rank(tr[k].l,x);
}

int query_num(int k,int x)
{
    if(k==0)return 0;
    if(x<=tr[tr[k].l].size)
        return query_num(tr[k].l,x);
    else if(x>tr[tr[k].l].size+tr[k].w)
        return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w);
    else return tr[k].v;
}

void query_pre(int k,int x)
{
    if(k==0)return;
    if(tr[k].v == x) {
        ans = k;
        return ;
    }
    if(tr[k].v<x)
    {
        ans=k;query_pre(tr[k].r,x);
    }
    else query_pre(tr[k].l,x);
}
void query_sub(int k,int x)
{
    if(k==0)return;
     if(tr[k].v == x) {
        ans = k;
        return ;
    }
    if(tr[k].v>x)
    {
        ans=k;query_sub(tr[k].l,x);
    }
    else query_sub(tr[k].r,x);
}
int m;
map<int,int > mp;
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF) {
        int cnt = 0 ,t1, t2 , x;
        root = 0;
        mp.clear();
        tr[root].size = 0;
        char ch[10];
        insert(root,0);
        insert(root,n+1);
        for(int i=1;i<=m;i++) {
            scanf("%s",ch);
            if(ch[0]==‘D‘) {
                scanf("%d",&x) ;
                if(mp[x]==0) {
                    insert(root,x);
                    mp[x] = 1;
                }last[++cnt] = x;

            }
            if(ch[0]==‘R‘) {
                if(!cnt) continue;
                if(mp[last[cnt]] == 1) {
                    del(root,last[cnt]);
                    mp[last[cnt]] = 0;
                }
                cnt--;
            }
            if(ch[0]==‘Q‘) {
                scanf("%d",&x);
                ans = 0;
                query_sub(root,x);
                t1= tr[ans].v ;
                ans = 0 ;
                query_pre(root,x) ;
                t2 = tr[ans].v;
                printf("%d\n", max(t1 -  t2 - 1,0));
            }
        }
    }
}

时间: 2024-10-07 03:29:29

HDU 1540 Tunnel Warfare 平衡树 / 线段树:单点更新,区间合并的相关文章

POJ 2892 Tunnel Warfare(线段树单点更新区间合并)

Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7876   Accepted: 3259 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally sp

hdu 1540 Tunnel Warfare【线段树】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目大意:抗日战争时期,各村庄被一条地道连接着(村庄排在一条线上),有三种操作: 第一种:某村庄被敌军摧毁: 第二种:修复上一个被摧毁的村庄: 第三种:查询与该村庄直接或间接链接的村庄有多少个(包括自己): 此题用线段树做,每个节点包含该区间从左端开始有多大连续区间ls,从右端向左有多大连续区间rs,该区间的最大连续区间mas: 代码如下: #include <iostream> #incl

hdu 3308 线段树单点更新 区间合并

http://acm.hdu.edu.cn/showproblem.php?pid=3308 学到两点: 1.以区间端点为开始/结束的最长......似乎在Dp也常用这种思想 2.分类的时候,明确标准逐层分类,思维格式: 条件一成立: { 条件二成立: { } else { } } else { 条件二成立: { } else { } } 上面的这种方式很清晰,如果直接想到那种情况iif(条件一 &条件二)就写,很容易出错而且把自己搞乱,或者情况不全,,,我就因为这WA了几次 3.WA了之后 ,

HDU 1540 Tunnel Warfare(线段树单点更新+区间合并)

Problem Description 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 vill

HDU 1540 Tunnel Warfare(线段树,单点更新,区间查询)

Problem Description 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 vill

POJ 题目2892 Tunnel Warfare(线段树单点更新查询,求单点所在最大连续区间长度)

Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7307   Accepted: 2997 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally sp

HDU 3308 LCIS (线段树&#183;单点更新&#183;区间合并)

题意  给你一个数组  有更新值和查询两种操作  对于每次查询  输出对应区间的最长连续递增子序列的长度 基础的线段树区间合并  线段树维护三个值  对应区间的LCIS长度(lcis)  对应区间以左端点为起点的LCIS长度(lle)  对应区间以右端点为终点的LCIS长度(lri)  然后用val存储数组对应位置的值  当val[mid + 1] > val[mid] 的时候就要进行区间合并操作了 #include <cstdio> #include <algorithm>

hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316 题意:给你n个点,m个操作,每次操作有3个整数t,a,b,t表示操作类型,当t=1时讲a点的值改成b:当t=0时,查询区间a,b之间最大的子序列和,这个子序列中的相邻的元素的原来的下标奇偶性都不同. 思路:这道题难点就在查询,其余都是模板,而根据查询,你只要分别把下一个区间的奇偶最大的情况分别比较,合并到上一个区间这样可以构建一个每个节点存有区间中奇开头偶开头,奇结尾,偶结尾这些区间情况的树.

HDU 1754 I Hate It 线段树 单点更新 区间最大值

1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8 #include<vector> 9 #include<cstring> 10 #include<stack> 11 #