链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610
题意:将一段[1, n]的区间,对于区间中的某些子区间染成不同的颜色,问染完色以后每种颜色的区间有几段(若为0不输出), 例如染完以后区间[1, 4]为1,[5, 6]为2, 故颜色为1的为1段, 2的为1段。
输入 :n, n个操作, 每一个操作, x, y, z 代表将[x, y]染成z颜色
解题思路:先按题意染色, 查询时用一个变量temp永远标记当前所遍历区间段的左边的颜色(temp标记的为整段区间为一个颜色的子区间的颜色, 同样查询也是对于这种区间计算),如果不同则将对应颜色的结果加一。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define lson ins<<1
#define rson ins<<1|1
#define merge tree[ins]=tree[lson]+tree[rson]
#define mid (r+l)/2
using namespace std;
const int Max = 200052;
int Hash[Max], ans[Max];
int temp;
struct node{
int x, y, z;
}data[Max>>1];
struct Tree {
int l, r;
int sum, lazy;
void updata(int x){
sum=(r-l+1);
lazy=x;
}
} tree[Max << 2];
inline void push_up(int ins){
if(tree[lson].sum||tree[rson].sum)tree[ins].sum=-1;
}
inline void build(int l, int r, int ins){
tree[ins].l=l, tree[ins].r=r,tree[ins].sum=0, tree[ins].lazy=-1;//没有颜色表示为-1
if(l<r){
build(l, mid, lson);
build(mid+1, r, rson);
}
}
inline void push_down(int ins){
int lazyval=tree[ins].lazy;
tree[ins].lazy=-1;
if(lazyval==-1)return;
tree[lson].updata(lazyval);
tree[rson].updata(lazyval);
}
inline void updata_tree(int ql, int qr, int ins, int add){
int l=tree[ins].l, r=tree[ins].r;
if(l>=ql&&r<=qr){
tree[ins].updata(add);
}
else {
push_down(ins);
if(ql<=mid)updata_tree(ql, qr, lson, add);
if(qr>mid)updata_tree(ql, qr, rson, add);
push_up(ins);
}
}
inline int query(int ins){
int l=tree[ins].l,r=tree[ins].r;//由于查询永远是先查询左子树后查询右子树, 故在查询时对于整段区间为一个颜色的可以直接用temp标记,并在下一次查询到另一个同样整段区间一个颜色的区间可以直接于temp相比较,因为这样的两个区间永远时由左到右相邻的
if(tree[ins].lazy!=-1||l==r){
if(tree[ins].lazy!=-1&&tree[ins].lazy!=temp)
ans[tree[ins].lazy]++;//如果不同则对应颜色的结果加一
temp=tree[ins].lazy;
}
else if(tree[ins].sum){
query(lson);
query(rson);
}
}
int main(){
int n;
while(~scanf("%d", &n)){
int max1=0, max2=0;
for(int a=1;a<=n; a++){
scanf("%d%d%d", &data[a].x, &data[a].y, &data[a].z);
max1=max(max1, data[a].y);
max2=max(max2, data[a].z);
}
build(1, max1, 1);
memset(ans, 0, sizeof(ans));
for(int a=1;a<=n;a++){
updata_tree(data[a].x+1, data[a].y, 1, data[a].z);
}
temp=-1;//初始化为没有颜色
query(1);
for(int a=0; a<=max2;a++){
if(ans[a]){
printf("%d %d\n", a, ans[a]);
}
}
printf("\n");
}
return 0;
}