zoukankan      html  css  js  c++  java
  • HDU1199 动态线段树 // 离散化

    附动态线段树AC代码

    http://acm.hdu.edu.cn/showproblem.php?pid=1199

    因为昨天做了一道动态线段树的缘故,今天遇到了这题没有限制范围的题就自然而然想到了动态线段树的解法,写完看题解发现原来只要离散化就好了(干。。),总结了一下这题和昨天hdu5367的区别在于,虽然都是两题范围超级大的线段树,但是昨天的强制要求在线求解,只能选择空间复杂度更大一些的动态线段树来求解,而今天的这题可以选择离线操作,因而可以采用先读入所有输入,离散化之后建树的方法来操作。下次遇到这样的题还是应当优先考虑离散化。

    在一个全部涂黑色的条子上涂上一些白色或黑色的片段,问最大白色片段。

    仅仅从线段树维护节点的角度上来看很简单,维护最大白色片段,左边最大白色片段,右边最大白色片段就好了。

    由于条子的长度长达1-INT_MAX;

    采用离散化,或者像我一样失了智去用动态线段树的方法,也能AC

    #include <map>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #define For(i, x, y) for(int i=x; i<=y; i++)  
    #define _For(i, x, y) for(int i=x; i>=y; i--)
    #define Mem(f, x) memset(f, x, sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i = 0; i <= N ; i ++) u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    using namespace std;
    typedef vector<int> VI;
    const double eps = 1e-9;
    const int maxn = 2010;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    inline int read()
    {
        int now=0;register char c=getchar();
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);now=now*10+c-'0',c=getchar());
        return now;
    }
    int N,M;
    struct Tree{
        LL sum;    //最大连续 
        LL lsum;   //左连续 
        LL rsum;   //右连续 
        int lt;
        int rt;
        int lazy;
        void init(){
            lsum = rsum = sum = lt = rt = 0;
            lazy = -1;
        }
    }tree[maxn * 60];
    int tot;
    void check(int &t){
        if(t) return;
        t = ++tot;
        tree[t].init();
    }
    void add(int &t,LL L,LL R,int v){
        if(v){
            tree[t].sum = tree[t].lsum = tree[t].rsum = R - L + 1;
        }else{
            tree[t].sum = tree[t].lsum = tree[t].rsum = 0;
        }
        tree[t].lazy = v;
    }
    void Pushdown(int& t,LL L,LL R){
        if(tree[t].lazy == -1) return;
        int &lt = tree[t].lt; int &rt = tree[t].rt;
        LL M = (L + R) >> 1;
        check(lt); check(rt);
        add(lt,L,M,tree[t].lazy);
        add(rt,M + 1,R,tree[t].lazy);
        tree[t].lazy = -1;
    }
    void Pushup(int t,LL L,LL R){
        int &ls = tree[t].lt; int &rs = tree[t].rt;
        LL M = (L + R) >> 1; 
        check(ls); check(rs);
        tree[t].sum = max(tree[ls].sum,tree[rs].sum);
        tree[t].sum = max(tree[t].sum,tree[ls].rsum + tree[rs].lsum);
        tree[t].lsum = tree[ls].lsum;
        if(tree[ls].lsum == M - L + 1){
            tree[t].lsum = tree[ls].lsum + tree[rs].lsum;
        } 
        tree[t].rsum = tree[rs].rsum;
        if(tree[rs].rsum == R - M){
            tree[t].rsum = tree[rs].rsum + tree[ls].rsum;
        }
    }
    void update(int &t,int q1,int q2,LL L,LL R,int v){
        check(t);
        if(q1 <= L && R <= q2){
            add(t,L,R,v);
            return;
        }
        Pushdown(t,L,R);
        LL m = (L + R) >> 1;
        if(q1 <= m) update(tree[t].lt,q1,q2,L,m,v);
        if(q2 > m) update(tree[t].rt,q1,q2,m + 1,R,v);
        Pushup(t,L,R);
    }
    LL Left,Right;
    void query(int t,LL L,LL R){
        if(L == R){
            Left = L;
            Right = R;
            return;
        }
        check(tree[t].lt); check(tree[t].rt);
        int ls = tree[t].lt; int rs = tree[t].rt;
        LL M = (L + R) >> 1;
        if(tree[ls].sum == tree[t].sum) query(ls,L,M);
        else if(tree[rs].sum == tree[t].sum) query(rs,M + 1,R);
        else{
            Left = M - tree[ls].rsum + 1;
            Right = M + tree[rs].lsum;
            return;
        }
     
    }
    int main()
    {
        while(~Sca(N)){
            LL L = 1; LL R = 2147483647;
            tot = 0;
            int root = 0;
            update(root,L,R,L,R,0);
            For(i,1,N){
                LL l,r;
                char op[3];
                scanf("%lld%lld%s",&l,&r,&op);
                if(op[0] == 'w'){
                    update(root,l,r,L,R,1);
                }else{
                    update(root,l,r,L,R,0);
                }
            }
            if(!tree[root].sum){
                puts("Oh, my god");
                continue;
            }
            query(root,L,R);
            printf("%lld %lld
    ",Left,Right);
        }
        return 0;
    }
     
  • 相关阅读:
    当上微软MVP了
    关于南京四校联合程序设计大赛
    毕业生的商业软件开发之路初入职场
    开源XDesigner ORM 框架设计
    中国计算机软件行业分析3软件倾销
    中国计算机软件行业分析6软件外包的缺陷
    搜狐首页出现一个硕大的错别字
    中国计算机软件行业分析4外企的商业贿赂
    大家快来玩转盘抽奖游戏(走在网页游戏开发的路上(七))
    走在网页游戏开发的路上(四)
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/9499713.html
Copyright © 2011-2022 走看看