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\n",ans);
 
    }
    return 0;
}

 

posted @ 2017-03-13 20:17  Fighting_Heart  阅读(256)  评论(0编辑  收藏  举报