• HDU1199 Color the Ball (线段树合并+离散化经典)


    与这道题相似的还有poj一道贴海报的题目,但这道题更加经典

    典型的线段树合并求区间子段和模型,但是不同的是加了一个离散化,这也是最难的地方

    本题思路:

    1.设计lmax,rmax tmax来表示左边最长连续,总共最长连续和右边最长连续

    2.设计懒标记为-1,0,1表示这区间是否都是黑或白或混合,如果不设懒标记,线段树的复杂度无法保证。

    3.以上这中模型的通解,那么下面就是离散化部分

    对于区间染色和区间合并问题,不能简单离散化,因为我们知道,这样会导致中间的部分值缺失,所以我们需要将每个位置的左右点都加进去保证不会覆盖。

    4.查询的时候一定要注意要找最小的,也就是越左越好

    5.我是用vector离散化,在求sum的时候一定要考虑好到底是什么减什么。

    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<string>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const int inf=0x3f3f3f3f;
    struct node{
        int l,r;
        int lmax;
        int rmax;
        int tmax;
        int lazy;
    }tr[N<<2];
    struct qi{
        int a;
        int b;
        string s;
    }q[2100];
    vector<int> num;
    void pushup(int u){
        tr[u].rmax=tr[u<<1|1].rmax;
        if(tr[u<<1|1].lazy==-1)
            tr[u].rmax+=tr[u<<1].rmax;
        tr[u].lmax=tr[u<<1].lmax;
        if(tr[u<<1].lazy==-1)
            tr[u].lmax+=tr[u<<1|1].lmax;
        tr[u].tmax=max(tr[u<<1].rmax+tr[u<<1|1].lmax,max(tr[u<<1].tmax,tr[u<<1|1].tmax));
        if(tr[u<<1].lazy==tr[u<<1|1].lazy)
            tr[u].lazy=tr[u<<1].lazy;
        else{
            tr[u].lazy=0;
        }
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]=(node){l,l,0,0,0,1};
        }
        else{
            tr[u]=(node){l,r,0,0,0,1};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
        }
    }
    void pushdown(int u){
        tr[u<<1].lazy=tr[u<<1|1].lazy=tr[u].lazy;
        if(tr[u].lazy==1){
            tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=0;
            tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=0;
        }
        else{
            tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=num[tr[u<<1].r-1]-num[tr[u<<1].l-2];
            tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=num[tr[u<<1|1].r-1]-num[tr[u<<1|1].l-2];
        }
        tr[u].lazy=0;
    }
    void modify(int u,int l,int r,int x){
        if(tr[u].l>=l&&tr[u].r<=r){
            tr[u].lazy=x;
            if(x==1){
                tr[u].lmax=tr[u].rmax=tr[u].tmax=0;
            }
            else{
                tr[u].lmax=tr[u].rmax=tr[u].tmax=num[tr[u].r-1]-num[tr[u].l-2];
            }
            return ;
        }
        if(tr[u].lazy!=0)
            pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r,x);
        if(r>mid){
            modify(u<<1|1,l,r,x);
        }
        pushup(u);
    }
    int find(int x){
        return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
    }
    int query(int u,int x){
        if(tr[u<<1].lmax==x){
            return num[tr[u].l-1];
        }
        if(tr[u].lazy)
            pushdown(u);
        if(tr[u<<1].tmax==x)
            return query(u<<1,x);
        if(tr[u<<1].rmax+tr[u<<1|1].lmax==x)
            return num[tr[u<<1].r-1]-tr[u<<1].rmax+1;
        else
            return query(u<<1|1,x);
    }
    int main(){
        int n;
        while(cin>>n){
            int i;
            if(n==0){
                cout<<"Oh,my god"<<endl;
                continue;
            }
            num.clear();
            for(i=1;i<=n;i++){
                cin>>q[i].a>>q[i].b>>q[i].s;
                if(q[i].a>q[i].b)
                    swap(q[i].a,q[i].b);
                num.push_back(q[i].a);
                num.push_back(q[i].b);
                num.push_back(q[i].a-1);
                num.push_back(q[i].a+1);
                num.push_back(q[i].b-1);
                num.push_back(q[i].b+1);
            }
            sort(num.begin(),num.end());
            num.erase(unique(num.begin(),num.end()),num.end());
            build(1,1,(int)num.size());
            for(i=1;i<=n;i++){
                int l=find(q[i].a);
                int r=find(q[i].b);
                if(q[i].s=="w"){
                    modify(1,l,r,-1);
                }
                else{
                    modify(1,l,r,1);
                }
            }
    
            int x=tr[1].tmax;
            if(x==0){
                cout<<"Oh,my god"<<endl;
            }
            else{
                int y1=query(1,x);
                int y2=y1+tr[1].tmax-1;
                cout<<y1<<" "<<y2<<endl;
            }
        }
    }
    View Code
  • 相关阅读:
    RTThread | 启动下一代RTOS演化
    开发者应该开始学习C++吗?
    用googleperftool分析程序的内存/CPU使用
    看书看累了,可以换看技术视频也是一种学习的方式
    分享:nginx virtuanenv django1.4 应用简单部署
    分享:不同编程语言之间转换的项目矩阵
    【EDUPEPN8508GS黄金版】EDUP EPN8508GS黄金版 迷你USB无线网卡【行情 报价 价格 评测】
    分享:20 本优秀的 Python 电子书
    说说设计模式~工厂方法模式(Factory Method)
    说说设计模式~简单工厂模式(Factory)
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12510903.html
Copyright © 2020-2023  润新知