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
  • 相关阅读:
    IOS Charles(代理服务器软件,可以用来拦截网络请求)
    Javascript中addEventListener和attachEvent的区别
    MVC中实现Area几种方法
    Entity Framework Code First 中使用 Fluent API 笔记。
    自定义JsonResult解决 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    An entity object cannot be referenced by multiple instances of IEntityChangeTracker 的解决方案
    Code First :使用Entity. Framework编程(8) ----转发 收藏
    Code First :使用Entity. Framework编程(6) ----转发 收藏
    Code First :使用Entity. Framework编程(5) ----转发 收藏
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3539399.html
Copyright © 2011-2022 走看看