HDU 1540<线段树,区间并>

题目连接
参考

题意:

维护各个点的连续的最大连续长度。

思路:

主要是维护一个区间的三个变量ll,f[i].l为起点向右的最大连续
长度,rl:f[i].r为起点向左的最大连续长度,ml:[l,r]区间内的
最大连续长度,便于合并。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100000+100;
struct node
{
    int l,r;
    int ll,rl,ml;
};
int a[maxn];
int sti[maxn];//sickc,数组的话更快,也更方便
int top=0;
node f[maxn*4];
void maketree(int i,int l,int r)
{
    f[i].l=l;
    f[i].r=r;
    f[i].ll=f[i].rl=f[i].ml=r-l+1;//刚开始都连续
    if(l==r)
        return ;
    int mid=(l+r)>>1;
    maketree(i<<1, l, mid);
    maketree(i<<1|1, mid+1, r);
}
void update(int i,int x,int v)
{
    if(f[i].l==f[i].r)//叶子结点
    {
        f[i].ll=f[i].rl=f[i].ml=v;//v=0||1;
        return ;
    }
    int mid=(f[i].l+f[i].r)>>1;
    if(x<=mid) update(i<<1, x, v);
    else update(i<<1|1, x, v);
    //合并操作:!
    //ml
    f[i].ml=max(f[i<<1].ml,f[i<<1|1].ml);
    f[i].ml=max(f[i].ml,f[i<<1].rl+f[i<<1|1].ll);
    //ll
    f[i].ll=f[i<<1].ll;
    if(f[i].ll==f[i<<1].r-f[i<<1].l+1)
        f[i].ll+=f[i<<1|1].ll;
    //rl
    f[i].rl=f[i<<1|1].rl;
    if(f[i].rl==f[i<<1|1].r-f[i<<1|1].l+1)
        f[i].rl+=f[i<<1].rl;
}
int  query(int i,int x)//寻找连续区间的最大值
{
    if(f[i].l==f[i].r||f[i].ml==f[i].r-f[i].l+1||f[i].ml==0)
    //是叶子节点||都连续||都不连续直接返回ml
        return f[i].ml;
    int mid=(f[i].l+f[i].r)>>1;
    if(x<=mid){
        if(x>=mid-f[i<<1].rl+1)//主要看代码
            return query(i<<1, x)+query(i<<1|1, mid+1);
        else
            return query(i<<1, x);
    }
    else {
        if(x<=mid+f[i<<1|1].ll)
            return query(i<<1, mid)+query(i<<1|1, x);
        else
            return query(i<<1|1, x);   
    }
}
int main ()
{
    int n,m;
    char s[5];
    while(~scanf("%d%d",&n,&m))//WA一次
    {
        top=0;
        maketree(1, 1, n);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s);
            if(s[0]!='R'){
                int t;
                scanf("%d",&t);
                if(s[0]=='D'){
                    sti[++top]=t;
                    update(1, t, 0);
                }
                else if(s[0]=='Q')
                    printf("%d
",query(1, t));
            }
            else
                update(1, sti[top--], 1);
        }
    }
    return 0;
}
想的太多,做的太少。
原文地址:https://www.cnblogs.com/pealicx/p/6115619.html