I

题意:在抗日战争期间,地道战在华北平原得到广泛的实施,一般而言,村庄通过一些隧道在一条线上连接,除了两端剩下的每个村庄都有两个相连。
侵略者会频繁的对这些村庄进行扫荡,并且摧他们的地道,当然八路军会把这一些已经被摧毁的村庄修复的,会优先修复最近被破坏的村庄。
分析:被这道题折磨了一上午啊,不过也学到了很多,尤其是这种涉及左右区间的。
*********************************************************************
#include<stdio.h>
#include<algorithm>
#include<stack>
using namespace std;

const int maxn = 50005;

struct node
{//sum代表区间种最大的连续区间,lsum代表左端能到达的最右端的个数
    int L, R, sum, lsum, rsum;
    int Mid(){return (L+R)/2;}
    int Len(){return (R-L+1);}
}a[maxn*4];

void Up(int r)
{
    a[r].lsum = a[r<<1].lsum, a[r].rsum = a[r<<1|1].rsum;

    if(a[r<<1].lsum == a[r<<1].Len())
        a[r].lsum = a[r<<1].lsum + a[r<<1|1].lsum;
    if(a[r<<1|1].rsum == a[r<<1|1].Len())
        a[r].rsum = a[r<<1|1].rsum + a[r<<1].rsum;

    a[r].sum = max(a[r].lsum, max(a[r].rsum, a[r<<1].rsum+a[r<<1|1].lsum));
}
void Build(int r, int L, int R)
{
    a[r].L = L, a[r].R = R;
    a[r].lsum = a[r].rsum = a[r].sum = a[r].Len();

    if(L == R)return ;

    Build(r<<1, L, a[r].Mid());
    Build(r<<1|1, a[r].Mid()+1, R);
}
void Insert(int r, int k, int e)
{
    if( a[r].L == a[r].R )
    {
        a[r].lsum = a[r].rsum = a[r].sum = e;
        return ;
    }

    if(k <= a[r].Mid())
        Insert(r<<1, k, e);
    else
        Insert(r<<1|1, k, e);

    Up(r);
}
int  Query(int r, int k)
{
    if(a[r].sum == 0)return 0;
    if(k < a[r].L+a[r].lsum)return a[r].lsum;//判断是否在左边
    if(k > a[r].R-a[r].rsum)return a[r].rsum;//判断是否在右边
    if(k > a[r<<1].R-a[r<<1].rsum && k < a[r<<1|1].L+a[r<<1|1].lsum)//判断是否在中间
        return a[r<<1].rsum + a[r<<1|1].lsum;

    if(k <= a[r].Mid())
        return Query(r<<1, k);
    else
        return Query(r<<1|1, k);
}

int main()
{
    int N, M;

    while(scanf("%d%d", &N, &M) != EOF)
    {
        int x; char s[10];
        stack<int> sta;

        Build(11, N);

        while(M--)
        {
            scanf("%s", s);

            if(s[0] == 'D')
            {
                scanf("%d", &x);
                Insert(1, x, 0);
                sta.push(x);
            }
            else if(s[0] == 'R' && sta.size())
            {
                Insert(1, sta.top(), 1);
                sta.pop();
            }
            else if(s[0] == 'Q')
            {
                scanf("%d", &x);
                printf("%d ", Query(1, x));
            }
        }
    }

    return 0; 

}

原文地址:https://www.cnblogs.com/liuxin13/p/4679551.html