• ZUFEOJ 2147 07染色带谜题


    2147: 07染色带谜题

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 170  解决: 21
    [提交][状态][讨论版][Edit] [TestData]

    题目描述

    现在给你一个长为N的染色带,有M种颜色,标号分别为0,1,2,…,M-1,染色带初始的颜色为标号0,现在对它进行K次操作,第i次操作,是对染色带的[Li,Ri]区间染上第Si种颜色(即把这段区间原来的颜色给覆盖掉),最后问你染色带进行这么多次操作后染色带上有几种颜色。

    输入

    输入包含多组数据,每组数据第一行包含3个正整数分别是N,M,K(0<N<=10000000,0<M<=10000,0<K<=10000),它们用空格隔开,接下来K行分别是3个整数Li ,Ri,Si,分别满足0<=Li <Ri<=N, 0<=Si<M。

    输出

    输出对于每组数据输出一个数字代表染色带上最后有几种颜色。

    样例输入

    2 2 0
    2 2 1
    0 2 1
    3 3 3
    0 2 1
    1 3 2
    2 3 0
    

    样例输出

    1
    1
    3

    首先吐槽一下题目,第一句,应该是$n+1$长度的吧。。。直接上了个线段树区间覆盖,写完一直$WA$,对拍去了,发现标程是错的,数据也是错的。搞笑的是这题是$2014$年学校校赛的题目,当时数据就是错的,但是现场有人$AC$。。现在我把数据改正确了,历史翻案。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
     
    int n,m,k;
    int L[100010],R[100010],s[100010];
    int p[100010],sz;
    int t[400010],y[100010];
    set<int>r;
     
    int get(int x)
    {
        int left =1,right =sz,res;
        while(left<=right)
        {
            int mid = (left + right)/2;
            if(p[mid]>x) right = mid-1;
            else if(p[mid]==x) res=mid,right = mid-1;
            else left = mid+1;
        }
        return res;
    }
     
    void pushDown(int rt)
    {
        if(t[rt]==-1) return ;
        t[2*rt] = t[rt];
        t[2*rt+1] = t[rt];
        t[rt]=-1;
    }
     
    void update(int LL,int RR,int col,int l,int r,int rt)
    {
        if(LL<=l&&r<=RR)
        {
            t[rt]=col;
            return ;
        }
     
        int m = (l+r)/2;
        pushDown(rt);
        if(LL<=m) update(LL,RR,col,l,m,2*rt);
        if(RR>m) update(LL,RR,col,m+1,r,2*rt+1);
    }
     
    void dfs(int l,int r,int rt)
    {
        if(l==r)
        {
            y[t[rt]]=1;
            return ;
        }
        int m = (l+r)/2;
        pushDown(rt);
        dfs(l,m,2*rt);
        dfs(m+1,r,2*rt+1);
    }
     
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            t[rt]=0;
            return ;
        }
     
        t[rt]=-1;
        int m = (l+r)/2;
        build(l,m,2*rt);
        build(m+1,r,2*rt+1);
    }
     
    int main()
    {
        //freopen("D:\out.txt","w",stdout);
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            sz=0;
            memset(t,0,sizeof t); memset(y,0,sizeof y); r.clear();
     
            for(int i=1;i<=k;i++)
            {
                scanf("%d%d%d",&L[i],&R[i],&s[i]);
                if(r.count(L[i])==0) sz++, p[sz]=L[i] , r.insert(L[i]);
                if(r.count(R[i])==0) sz++, p[sz]=R[i] , r.insert(R[i]);
     
                if(r.count(L[i]-1)==0&&L[i]-1>=0) sz++, p[sz]=L[i]-1 , r.insert(L[i]-1);
                if(r.count(L[i]+1)==0&&L[i]+1<=n) sz++, p[sz]=L[i]+1 , r.insert(L[i]+1);
     
                if(r.count(R[i]-1)==0&&R[i]-1>=0) sz++, p[sz]=R[i]-1 , r.insert(R[i]-1);
                if(r.count(R[i]+1)==0&&R[i]+1<=n) sz++, p[sz]=R[i]+1 , r.insert(R[i]+1);
            }
     
            if(r.count(0)==0) sz++, p[sz]=0 , r.insert(0);
            if(r.count(n)==0) sz++, p[sz]=n , r.insert(n);
     
            sort(p+1,p+1+sz);
     
            build(1,sz,1);
            for(int i=1;i<=k;i++) L[i] = get(L[i]), R[i] = get(R[i]);
            for(int i=1;i<=k;i++) update(L[i],R[i],s[i],1,sz,1);
     
            dfs(1,sz,1);
            int ans=0;
            for(int i=0;i<=100000;i++) ans=ans+y[i];
            printf("%d
    ",ans);
     
        }
        return 0;
    }
  • 相关阅读:
    chkconfig命令
    Office 2010 与搜狗输入法兼容问题
    【转】WAS入门简介
    UTF8GB2312GBK
    System.getProperty
    Hibernate 事务方法保存clob类型数据
    Eclipse 或者 Myeclipse 提示选择工作空间设置
    request
    那些操蛋的人生
    Java新手入门很重要的几个基本概念
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6544815.html
Copyright © 2020-2023  润新知