ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】

Count the Colors

Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Submit Status Practice ZOJ 1610

Description

Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.

Your task is counting the segments of different colors you can see at last.

Input

The first line of each data set contains exactly one integer n, 1 <= n <= 8000, equal to the number of colored segments.

Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:

x1 x2 c

x1 and x2 indicate the left endpoint and right endpoint of the segment, c indicates the color of the segment.

All the numbers are in the range [0, 8000], and they are all integers.

Input may contain several data set, process to the end of file.

Output

Each line of the output should contain a color index that can be seen from the top, following the count of the segments of this color, they should be printed according to the color index.

If some color can‘t be seen, you shouldn‘t print it.

Print a blank line after every dataset.

Sample Input

5
0 4 4
0 3 1
3 4 2
0 2 2
0 2 3
4
0 1 1
3 4 1
1 3 2
1 3 1
6
0 1 0
1 2 1
2 3 1
1 2 0
2 3 0
1 2 1

Sample Output

1 1
2 1
3 1

1 1

0 2
1 1

错误点:在刚开始以为n就是树的最大范围了,然后一直报段错误(RE),后来发现maxn才是,解决后又wa了几次。还有就是(2,3,0)和(4,5,0)其实是两段,需要注意。然后参考网上的一种写法就过了,至于我的为啥没过,但是别的为啥过了,我也很不解。

解题思路:区间替换、转点为线,统计段数。

/*AC代码*/

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int maxn=50000;
int col[maxn*4];
int Hash[maxn*2];
int tmp[maxn*2];
int k;
void PushDown(int rt){

    if(col[rt]>=0){

        col[rt*2]=col[rt];
        col[rt*2+1]=col[rt];
        col[rt]=-1;
    }
}
void update(int rt,int L,int R,int l_ran,int r_ran,int _col){

    if(l_ran<=L&&R<=r_ran){

        col[rt]=_col;
        return ;
    }
    PushDown(rt);
    if(l_ran<=mid){

        update(lson,l_ran,r_ran,_col);
    }
    if(r_ran>mid){

        update(rson,l_ran,r_ran,_col);
    }
}
void query(int rt,int L,int R){

    if(col[rt]>=0){

        for(int i=L;i<=R;i++){      //区别在这里

            tmp[i]=col[rt];
        }                           //区别在这里
        col[rt]=-1;
        return ;
    }
    if(L==R)
        return ;
    query(lson);
    query(rson);
}
void get_ans(int n){

    if(tmp[0]>=0)
        Hash[tmp[0]]=1;
    for(int i=1;i<n;i++){

        if(tmp[i]!=tmp[i-1]){

            Hash[tmp[i]]++;
        }
    }
}
void debug2(){

    for(int i=0;i<k;i++){

        printf("..%d %d\n",i,tmp[i]);
    }
}
int main(){

    int n;
    while(scanf("%d",&n)!=EOF ){

        int ta,tb,tc;
        memset(tmp,-1,sizeof(tmp));
        memset(col,-1,sizeof(col));
        for(int i=0;i<n;i++){

            scanf("%d%d%d",&ta,&tb,&tc);
            update(1,0,maxn,ta*2,tb*2,tc);
        }
        memset(Hash,0,sizeof(Hash));
        k=0;
        query(1,0,maxn);
     //   printf("%d\n",k);
     //   debug2();
       // get_ans(k);
        for(int i=0;i<maxn;i++){    //区别在这里

            if(tmp[i]!=-1){
                int j;
                for( j=i;j<maxn&&tmp[i]==tmp[j];j++);
                Hash[tmp[i]]++;
                i=j-1;
            }
        }                           //区别在这里
        for(int i=0;i<maxn+20;i++){

            if(Hash[i]){

                printf("%d %d\n",i,Hash[i]);
            }

        } printf("\n");
    }
    return 0;
}

/*WA代码*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int maxn=50000;
int col[maxn*4];
int Hash[maxn*2];
int tmp[maxn*2];
int k=0;
void PushDown(int rt){

    if(col[rt]>=0){

        col[rt*2]=col[rt];
        col[rt*2+1]=col[rt];
        col[rt]=-1;
    }
}
void update(int rt,int L,int R,int l_ran,int r_ran,int _col){

    if(l_ran<=L&&R<=r_ran){

        col[rt]=_col;
        return ;
    }
    PushDown(rt);
    if(l_ran<=mid){

        update(lson,l_ran,r_ran,_col);
    }
    if(r_ran>mid){

        update(rson,l_ran,r_ran,_col);
    }
}
void query(int rt,int L,int R){

    if(col[rt]>=0){

        tmp[k++]=col[rt];       //区别在这里
        col[rt]=-1;
        return ;
    }
    if(L==R)
        return ;
    query(lson);
    query(rson);
}
void get_ans(int n){

    if(tmp[0]>=0)
        Hash[tmp[0]]=1;
    for(int i=1;i<n;i++){

        if(tmp[i]!=tmp[i-1]){

            Hash[tmp[i]]++;
        }
    }
}
void debug2(){

    for(int i=0;i<k;i++){

        printf("..%d %d\n",i,tmp[i]);
    }
}
int main(){

    int n;
    while(scanf("%d",&n)!=EOF ){

        int ta,tb,tc;
        memset(col,-1,sizeof(col));
        for(int i=0;i<n;i++){

            scanf("%d%d%d",&ta,&tb,&tc);
            update(1,0,maxn,ta*2,tb*2,tc);
        }
        memset(Hash,0,sizeof(Hash));
        k=0;
        query(1,0,maxn);
     //   printf("%d\n",k);
     //   debug2();
        get_ans(k);                     //区别在这里
        for(int i=0;i<maxn+20;i++){

            if(Hash[i]){

                printf("%d %d\n",i,Hash[i]);
            }

        } printf("\n");
    }
    return 0;
}

  

时间: 2024-08-07 00:15:56

ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】的相关文章

ZOJ 1610 Count the Colors(线段树,区间覆盖,单点查询)

Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can s

ZOJ 1610 Count the Colors (线段树成段更新)

题意 : 给出 n 个染色操作,问你到最后区间上能看见的各个颜色所拥有的区间块有多少个 分析 : 使用线段树成段更新然后再暴力查询总区间的颜色信息即可,这里需要注意的是给区间染色,而不是给点染色,所以对于区间(L, R)我们只要让左端点+1即可按照正常的线段树操作来做. #include<bits/stdc++.h> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; co

ZOJ - 1610 Count the Colors 线段树区间修改

Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can see at last. InputThe first line of each data set contains exactly o

ZOJ 1610 Count the Colors(线段树,但暴力未必不行)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 Description Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different color

ZOJ 1610 Count the Color(线段树)

描述 Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.Your task is counting the segments of different colors you can see at last. Input The first line of each data set contains exactl

ZOJ 1610 Count the Colors (线段树区间更新)

题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头输出. //ZOJ 1610 #include <cstdio> #include <cstring> #include <iostream> using namespace std ; int p[8010*4],lz[8010*4] ,hashh[8010*4],has

zoj 1610 Count the Colors

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=610 先用线段树维护区间颜色的覆盖,然后在把区间的颜色映射到数组,再从数组统计颜色. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 100000 5 using namespace std; 6 7 int n; 8 int min1; 9

ZOJ 1610 Count the Colors【题意+线段树区间更新&amp;&amp;单点查询】

任意门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent

Zoj 1610 Count the Colors (线段树+区间更新+暴力计数)

题目大意: 有n次操作,每次都是对一根线中的一段区间进行染色(颜色并不相同),有时候后面的颜色有可能覆盖前面的颜色,问最后涂完色,能看到的颜色有几种,每种颜色有几部分? 解题思路: 这个题目建树的时候有些不同,并不是以点为对象,而是以区间为对象,很明显是对线段树的区间进行操作,更新的时候要以区间为单位,还有就是计算每个区间出现几次的时候可以根据线段树的建树特征对树进行遍历求解. 1 #include <cstdio> 2 #include <cstring> 3 #include