题意,给你n个 x,y,c,意思就是区间[x,y]被染成C色,但是颜色会被覆盖的,染色操作完成以后 问你每种颜色有多少段 并输出颜色编号id跟段数cnt
经典问题,不过写的有点撮吧,没去看别人的,这个方法应该是最传统的最普通的,常规的开数组记录,也许大神们有更高端的方法
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>
#define ll long long
#define LL __int64
#define eps 1e-8
#define inf 0xfffffff
//const LL INF = 1LL<<61;
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;
const int N = 8000 + 5;
typedef struct Node {
int l,r;
int col;
};
Node tree[N * 4];
int color[N];
int ans[N];
void init() {
memset(color,-1,sizeof(color));
memset(ans,0,sizeof(ans));
}
void build(int l,int r,int id) {
tree[id].l = l;
tree[id].r = r;
tree[id].col = -1;
if(l == r)return;
int mid = (l + r)/2;
build(l,mid,id<<1);
build(mid+1,r,id<<1|1);
}
void cal(int id) {
if(tree[id].col > -1) {
tree[id<<1].col = tree[id].col;
tree[id<<1|1].col = tree[id].col;
tree[id].col = -1;
}
}
void update(int l,int r,int id,int col) {
if(tree[id].col == col)return;
if(l <= tree[id].l && r >= tree[id].r) {
tree[id].col = col;return;
}
cal(id);
int mid = (tree[id].l + tree[id].r)/2;
if(r <= mid)update(l,r,id<<1,col);
else if(l > mid)update(l,r,id<<1|1,col);
else {
update(l,mid,id<<1,col);
update(mid+1,r,id<<1|1,col);
}
}
void query(int l,int r,int id) {
if(tree[id].col > -1) {
for(int i=tree[id].l;i<=tree[id].r;i++)
color[i] = tree[id].col;
return;
}
if(tree[id].l == tree[id].r)return;
int mid = (tree[id].l + tree[id].r)/2;
if(r <= mid)query(l,r,id<<1);
else if(l > mid)query(l,r,id<<1|1);
else {
query(l,mid,id<<1);
query(mid+1,r,id<<1|1);
}
}
int main() {
int n;
while(scanf("%d",&n) == 1) {
int q = n;
init();
build(1,N,1);
int x,y,c;
while(q--) {
scanf("%d %d %d",&x,&y,&c);
x++;
update(x,y,1,c);
}
query(1,N,1);
for(int i=1;i<N;i++)
if(color[i - 1] != color[i])
if(color[i] > -1)
ans[color[i]]++;
for(int i=0;i<N;i++)
if(ans[i])
printf("%d %d\n",i,ans[i]);
puts("");
}
return 0;
}
ZOJ1610 Count the Colors 经典线段树染色问题,布布扣,bubuko.com
ZOJ1610 Count the Colors 经典线段树染色问题
原文:http://blog.csdn.net/yitiaodacaidog/article/details/36448637