zoukankan      html  css  js  c++  java
  • 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;
    }
    
    想的太多,做的太少。
  • 相关阅读:
    CSS基础
    HTML基础
    JavaScript基础目录
    python 面向对象的基本概念(未完待续)
    python核心编程笔记(转)
    转: cJSON的使用方法
    转: C语言交换两个变量数值的几种方法
    转: 100个gdb小技巧项目
    转:C语言中的typeof关键字
    转:安全起见,小心使用C语言realloc()函数
  • 原文地址:https://www.cnblogs.com/pealicx/p/6115619.html
Copyright © 2011-2022 走看看