zoukankan      html  css  js  c++  java
  • ZOJ 2301 / HDU 1199 Color the Ball 离散化+线段树区间连续最大和

    题意:给你n个球排成一行,初始都为黑色,现在给一些操作(L,R,color),给[L,R]区间内的求染上颜色color,'w'为白,'b'为黑。问最后最长的白色区间的起点和终点的位置。

    解法:先离散化,为了防止离散后错误,不仅将L,R离散,还要加入L+1,L-1,R+1,R-1一起离散,这样就绝不会有问题了。然后建线段树,线段树维护四个值:

    1.col  区间颜色  0 表示黑  1 表示白  -1表示无标记

    2.maxi 区间内最大白区间的长度,由于白色用1表示,所以最大白区间的长度即为区间最大连续和

    3.lmax 从区间左端开始的最大白区间长度

    4.rmax 从区间右端开始的最大白区间长度

    然后更新,查询,就跟普通求区间连续最大和无异了

    代码:

    #include <iostream>
    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    #define N 14007
    
    struct node
    {
        int lmax,rmax,maxi,col;
    }tree[4*N];
    int num[N],x[N];
    int L[2005],R[2005];
    char ss[2005][3];
    map<int,int> mp;
    
    void pushup(int l,int r,int rt)
    {
        tree[rt].lmax = tree[2*rt].lmax;
        tree[rt].rmax = tree[2*rt+1].rmax;
        tree[rt].maxi = max(max(tree[2*rt].maxi,tree[2*rt+1].maxi),tree[2*rt].rmax+tree[2*rt+1].lmax);
        int mid = (l+r)/2;
        int L = x[mid]-x[l-1];  //真实的长度
        int R = x[r]-x[mid];
        if(tree[2*rt].lmax == L)
            tree[rt].lmax += tree[2*rt+1].lmax;
        if(tree[2*rt+1].rmax == R)
            tree[rt].rmax += tree[2*rt].rmax;
    }
    
    void pushdown(int l,int r,int rt)
    {
        if(tree[rt].col != -1)
        {
            tree[2*rt].col = tree[2*rt+1].col = tree[rt].col;
            int mid = (l+r)/2;
            int L = x[mid]-x[l-1];
            int R = x[r]-x[mid];
            tree[2*rt].maxi = tree[2*rt].lmax = tree[2*rt].rmax = L*tree[rt].col;
            tree[2*rt+1].maxi = tree[2*rt+1].lmax = tree[2*rt+1].rmax = R*tree[rt].col;
            tree[rt].col = -1;
        }
    }
    void build(int l,int r,int rt)
    {
        tree[rt].maxi = tree[rt].lmax = tree[rt].rmax = 0;
        tree[rt].col = -1;
        if(l == r) return;
        int mid = (l+r)/2;
        build(l,mid,2*rt);
        build(mid+1,r,2*rt+1);
    }
    
    void update(int l,int r,int aa,int bb,int col,int rt)
    {
        if(aa <= l && bb >= r)
        {
            tree[rt].col = col;
            tree[rt].maxi = tree[rt].lmax = tree[rt].rmax = col*(x[r]-x[l-1]);
            return;
        }
        pushdown(l,r,rt);
        int mid = (l+r)/2;
        if(aa <= mid)
            update(l,mid,aa,bb,col,2*rt);
        if(bb > mid)
            update(mid+1,r,aa,bb,col,2*rt+1);
        pushup(l,r,rt);
    }
    
    int query(int l,int r,int rt)
    {
        if(l == r) return x[l];
        int mid = (l+r)/2;
        pushdown(l,r,rt);
        if(tree[2*rt].maxi == tree[1].maxi)   //tree[1]  not  tree[rt]
            return query(l,mid,2*rt);
        else if(tree[2*rt].rmax+tree[2*rt+1].lmax == tree[1].maxi)
            return x[mid]-tree[2*rt].rmax+1;
        else
            return query(mid+1,r,2*rt+1);
    }
    
    int main()
    {
        int n,i,j,k;
        while(scanf("%d",&n)!=EOF)
        {
            mp.clear();
            for(i=1;i<=n;i++)
            {
                scanf("%d%d%s",&L[i],&R[i],ss[i]);
                num[6*i-5] = L[i]-1;
                num[6*i-4] = L[i];
                num[6*i-3] = L[i]+1;
                num[6*i-2] = R[i]-1;
                num[6*i-1] = R[i];
                num[6*i] = R[i]+1;
            }
            sort(num+1,num+6*n+1);
            int ind = unique(num+1,num+6*n+1)-num-1;
            int now = 0;
            x[0] = 0;
            for(i=1;i<=ind;i++)
            {
                x[++now] = num[i];
                mp[num[i]] = now;
            }
            build(1,now,1);
            for(i=1;i<=n;i++)
            {
                int ka = mp[L[i]];
                int kb = mp[R[i]];
                if(ss[i][0] == 'w')
                    update(1,now,ka,kb,1,1);
                else
                    update(1,now,ka,kb,0,1);
            }
            if(tree[1].maxi <= 0)
                puts("Oh, my god");
            else
            {
                int left = query(1,now,1);
                int right = left+tree[1].maxi-1;
                printf("%d %d
    ",left,right);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    jquery获取transform里面的值
    H5左滑删除JS插件
    IOS微信浏览器点击事件不起作用问题
    jquery获取不了ajax动态添加的内容的解决办法
    H5跟ios、android交互跟数据对接
    JS图片赖加载例子
    苹果手机浏览器下拉会闪动的解决办法
    jquery.rotate.js可选抽奖次数和中奖内容的转盘抽奖demo
    Html5的localStorage与sessionStorage五种循序渐进的使用方法
    tar 「解/壓」 包
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3932568.html
Copyright © 2011-2022 走看看