HDU 1540 Tunnel Warfare(区间合并)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1540

题意:给一个村子求直接和间接和它连着的村子有多少个

思路:

待测代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
const int inf = 0x3f3f3f3f;//1061109567
typedef long long LL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 50010;
int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2];
int st[maxn];
using namespace std;
void pushup(int rt,int m)
{
    lsum[rt] = lsum[rt<<1];
    rsum[rt] = rsum[rt<<1|1];
    if(lsum[rt] == (m>>1)) lsum[rt] += lsum[rt<<1|1];
    if(rsum[rt] == m-(m>>1)) rsum[rt] += rsum[rt<<1];
    msum[rt] = max(rsum[rt<<1]+lsum[rt<<1|1],max(msum[rt<<1],msum[rt<<1|1]));
}
void update(int v,int c,int l,int r,int rt)
{
    if(l == r)
    {
        rsum[rt]=lsum[rt]=msum[rt]=c?0:1;
        return;
    }//每次更新的都是单独一个点,所以没有pushdown()
    int m = (l+r)>>1;
    if(v<=m) update(v,c,lson);
    if(v>m) update(v,c,rson);
    pushup(rt,r-l+1);
}
int query(int c,int l,int r,int rt)
{
    if(l == r || msum[rt] == 0 || msum[rt] == r-l+1)
        return msum[rt];
    int m = (l+r)>>1;
    if(c <= m)
    {
        if(c >= m-rsum[rt<<1]+1)
            return query(c,lson)+query(m,rson);
        else
            return query(c,lson);
    }
    else
    {
        if(c <= m+lsum[rt<<1|1]-1)
            return query(m,lson)+query(c,rson);
        else
            return query(c,rson);
    }
}
void build(int l,int r,int rt)
{
    lsum[rt]=rsum[rt]=msum[rt]=r-l+1;
    if(l == r) return;
    int m = (l+r)>>1;
    build(lson);
    build(rson);
}
int main()
{
    int n,m,a;
    char op[2];
    while(scanf("%d%d",&n,&m) != EOF)
    {
        build(1,n,1);
        int top=0;
        while(m--)
        {
            scanf("%s",op);
            if(op[0] == 'D')
            {
                scanf("%d",&a);
                update(a,1,1,n,1);
                st[top++] = a;
            }
            else if(op[0] == 'Q')
            {
                scanf("%d",&a);
                int sum = query(a,1,n,1);
                printf("%d\n",sum);
            }
            else if(op[0] == 'R')
            {
                int x =st[top--];
                update(x,0,1,n,1);
            }
        }
    }
    return 0;
}


你可能感兴趣的:(HDU 1540 Tunnel Warfare(区间合并))