zoukankan      html  css  js  c++  java
  • HDU 3397 Sequence Operation

        线段树较复杂题,涵盖了线段树的大部分操作。

        这题节点维护:

        ls:左边最长连续1的长度, rs:右边最长连续1的长度  , ms:整个区间的最长连续1的长度 , sum:区间内1的个数  ,mark:操作懒标记

        将取反操作单独做一个函数来处理。

        具体维护见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 100027
    
    struct node
    {
        int ls,rs,ms;
        int sum;
        int mark;
    }tree[4*N];
    
    int a[N];
    int n,m;
    
    void pushup(int l,int r,int rt)
    {
        int mid = (l+r)/2;
        tree[rt].sum = tree[2*rt].sum + tree[2*rt+1].sum;
        tree[rt].ls = tree[2*rt].ls;
        if(tree[rt].ls == mid-l+1)
            tree[rt].ls += tree[2*rt+1].ls;
        tree[rt].rs = tree[2*rt+1].rs;
        if(tree[rt].rs == r-mid)
            tree[rt].rs += tree[2*rt].rs;
        tree[rt].ms = max(max(tree[2*rt].ms,tree[2*rt+1].ms),tree[2*rt].rs+tree[2*rt+1].ls);
    }
    
    void pushdown(int l,int r,int rt)
    {
        int mid = (l+r)/2;
        if(tree[rt].mark != -1)
        {
            tree[2*rt].mark = tree[2*rt+1].mark = tree[rt].mark;
            tree[2*rt].sum = tree[rt].mark*(mid-l+1);
            tree[2*rt+1].sum = tree[rt].mark*(r-mid);
            tree[2*rt].ms = tree[2*rt].ls = tree[2*rt].rs = tree[2*rt].sum;
            tree[2*rt+1].ms = tree[2*rt+1].ls = tree[2*rt+1].rs = tree[2*rt+1].sum;
            tree[rt].mark = -1;
        }
    }
    
    void build(int l,int r,int rt)
    {
        if(l == r)
        {
            tree[rt].sum = tree[rt].ms = tree[rt].ls = tree[rt].rs = a[l];
            tree[rt].mark = a[l];
            return;
        }
        tree[rt].mark = -1;
        int mid = (l+r)/2;
        build(l,mid,2*rt);
        build(mid+1,r,2*rt+1);
        pushup(l,r,rt);
    }
    
    void update_1(int l,int r,int aa,int bb,int op,int rt)
    {
        if(aa<=l && bb>=r)
        {
            if(op == 0)
                tree[rt].ms = tree[rt].ls = tree[rt].rs = tree[rt].sum = 0;
            else
                tree[rt].ms = tree[rt].ls = tree[rt].rs = tree[rt].sum = r-l+1;
            tree[rt].mark = op;
            return;
        }
        pushdown(l,r,rt);
        int mid = (l+r)/2;
        if(aa<=mid)
            update_1(l,mid,aa,bb,op,2*rt);
        if(bb>mid)
            update_1(mid+1,r,aa,bb,op,2*rt+1);
        pushup(l,r,rt);
    }
    
    void update_2(int l,int r,int aa,int bb,int rt)
    {
        if(aa<=l && bb>=r && tree[rt].mark != -1)
        {
            tree[rt].mark = abs(tree[rt].mark - 1);
            if(tree[rt].mark)
                tree[rt].sum = tree[rt].ms = tree[rt].ls = tree[rt].rs = r-l+1;
            else
                tree[rt].sum = tree[rt].ms = tree[rt].ls = tree[rt].rs = 0;
            return;
        }
        pushdown(l,r,rt);
        int mid =(l+r)/2;
        if(aa<=mid)
            update_2(l,mid,aa,bb,2*rt);
        if(bb>mid)
            update_2(mid+1,r,aa,bb,2*rt+1);
        pushup(l,r,rt);
    }
    
    int query_3(int l,int r,int aa,int bb,int rt)
    {
        if(aa>r || bb<l)
            return 0;
        if(aa<=l && bb>=r)
            return tree[rt].sum;
        pushdown(l,r,rt);
        int mid = (l+r)/2;
        int res = 0;
        if(aa<=mid)
            res += query_3(l,mid,aa,bb,2*rt);
        if(bb>mid)
            res += query_3(mid+1,r,aa,bb,2*rt+1);
        return res;
    }
    
    int query_4(int l,int r,int aa,int bb,int rt)
    {
        if(aa<=l && bb>=r)
            return tree[rt].ms;
        pushdown(l,r,rt);
        int mid = (l+r)/2;
        if(bb<=mid)
            return query_4(l,mid,aa,bb,2*rt);
        else if(aa>mid)
            return query_4(mid+1,r,aa,bb,2*rt+1);
        else
        {
            int Lf = query_4(l,mid,aa,bb,2*rt);
            int Rt = query_4(mid+1,r,aa,bb,2*rt+1);
            int tmp = min(tree[2*rt].rs,mid-aa+1) + min(tree[2*rt+1].ls,bb-mid);
            return max(max(Lf,Rt),tmp);
        }
    }
    
    int main()
    {
        int t,i;
        int aa,bb,op;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(i=1;i<=n;i++)
                scanf("%d",&a[i]);
            build(1,n,1);
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&op,&aa,&bb);
                aa++;bb++;
                if(op<2)
                    update_1(1,n,aa,bb,op,1);
                else if(op == 2)
                    update_2(1,n,aa,bb,1);
                else if(op == 3)
                    printf("%d
    ",query_3(1,n,aa,bb,1));
                else
                    printf("%d
    ",query_4(1,n,aa,bb,1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    echarts 算百分比与js toFixed算出来的百分比不一致的问题。
    VUE, Vue Router Tab 显示动态页签名称。
    [日常坑]前端j's数据导出excel,导出的文件损坏
    [最新 | Build 3211]Sublime Text 2.x, 3.x 许可License集合
    图片滤波
    electron-ipc通信性能分析
    设计vue3的请求实体工厂
    canvas-修改图片亮度
    canvas性能-drawImage渲染图片
    基于windows配置gitlab-runner
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3539399.html
Copyright © 2011-2022 走看看