zoukankan      html  css  js  c++  java
  • hdu 1540 Tunnel Warfare

    时隔一年做了这道历史悠久的题目,之前不知道是什么原因写到一半不写了,这次再看这道题,有了些思路,其实并不难,只是要把那些条件分开,不可混淆。

    线段树区间合并,主要是进行合并。

    /*
    题意:D代表破坏村庄,
    R代表修复最后被破坏的那个村庄,
    Q代表询问包括x在内的最大连续区间是多少
    */
    #include <iostream>
    #include <cstdio>
    #include <stack>
    #include <cstring>
    
    using namespace std;
    
    const int maxn=50005;
    #define lson rt<<1
    #define rson rt<<1|1
    
    struct st
    {
        int l,r;
        int lsum, rsum, sum;
        int mid()
        {
            return (l+r)>>1;
        }
        int len()
        {
            return (r-l+1);
        }
    }a[maxn<<2];
    
    void Build_Tree(int rt,int l,int r)
    {
        a[rt].l = l;
        a[rt].r = r;
        a[rt].lsum = a[rt].rsum = a[rt].sum = a[rt].len();
        if(l==r)
        {
            return ;
        }
        Build_Tree(lson, l, a[rt].mid());
        Build_Tree(rson, a[rt].mid()+1, r);
    }
    
    void pushdown(int rt)//进行合并
    {
        a[rt].lsum = a[lson].lsum;
        a[rt].rsum = a[rson].rsum;
        if(a[lson].lsum==a[lson].len())
            a[rt].lsum = a[lson].lsum+a[rson].lsum;
        if(a[rson].lsum==a[rson].len())
            a[rt].rsum = a[lson].rsum+a[rson].lsum;
    
        a[rt].sum = max(a[rt].rsum, a[rt].lsum);
        a[rt].sum = max(a[rt].sum, a[lson].rsum+a[rson].lsum);
    }
    
    void change(int rt, int index, int x)
    {
        if(a[rt].l == index && a[rt].r == index)
        {
            a[rt].sum = a[rt].lsum = a[rt].rsum = x;
            return ;
        }
        if(index<=a[rt].mid())
            change(lson, index, x);
        else
            change(rson, index, x);
        pushdown(rt);
    }
    
    int Query(int rt, int index)
    {
        if(a[rt].sum==0)//找到一点
            return 0;
        if(index<a[rt].l+a[rt].lsum)//左端区间上
            return a[rt].lsum;
        if(index>a[rt].r-a[rt].rsum)//右端区间上
            return a[rt].rsum;
        if(index>a[lson].r-a[lson].rsum && index<a[rson].l+a[rson].lsum)//中间
            return a[lson].rsum+a[rson].lsum;
    
        if(index<=a[rt].mid())
            return Query(lson, index);
        else
            return Query(rson, index);
    }
    
    int main()
    {
        int m, n;
        char str[10];
        stack<int> sta;
        while(~scanf("%d%d",&n,&m))
        {
            while(!sta.empty())
                sta.pop();
            Build_Tree(1,1,n);
            int x;
            for(int i=1;i<=m;i++)
            {
                scanf("%s",str);
    
                if(str[0] == 'D')
                {
                    scanf("%d", &x);
                    sta.push(x);
                    change(1, x, 0);
                }
                else if(str[0] == 'Q')
                {
                    scanf("%d", &x);
                    int ans = Query(1, x);
                    printf("%d
    ", ans);
                }
                else if(!sta.empty())
                {
                    x = sta.top();
                    sta.pop();
                    change(1, x, 1);
                }
            }
        }
    
        return 0;
    }
  • 相关阅读:
    1004: 画图
    1002: 数字排序问题
    1003: 相邻数对问题
    1001: 图像旋转问题
    1000: 数塔
    springday05-go1
    springday04-go2
    springday04-go1
    springday03-go2
    Android—PopupWindow的简单使用
  • 原文地址:https://www.cnblogs.com/mengzhong/p/4712358.html
Copyright © 2011-2022 走看看