版权声明:本文是博主乱写的文章,可以随便转载 https://blog.csdn.net/weixin_43768644/article/details/89386017
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=610
解题思路:思路跟我之前写的POJ 2528差不多。
https://blog.csdn.net/weixin_43768644/article/details/89341259
区别是这题是要输出所有看得见的颜色,以及对应这种颜色有几段。
按顺序讲一下代码。
PART 1:
主函数中:找到建树的右界,以及初始化,build()将区间所有点染为8002
int MAXN = 1;
for (int i = 1;i<=n;i++){
scanf("%d %d %d",x+i,y+i,c+i);
x[i]++,c[i]++;
MAXN = max(MAXN,y[i]);
}
///init
build(1,1,MAXN);
//memset(tree,0,sizeof tree);
for (int i=0;i<=8000;i++) ans[i] = sum[i] = 0;
for (int i = 1;i<=n;i++){
if (x[i]<=y[i]) update(x[i],y[i],c[i],1,1,MAXN);
}
主函数外:
对于每次给出区间进行更新,初始都染色为8002
这样给出 2
1 3 1
6 8 1
这样的数据就没有问题了,之前我初始化为0应该就是一直wa在这个地方 。看一下我那个poj2528题解应该就能体会到了。 维护的是一段区间内存在的颜色,如果一段区间是一种颜色中间却断了很多段,按照之前的思路,统计出的答案会是1,显然错误。这里把初始化的无色当做一种颜色,就没问题了。
#define mid int m = l+r>>1
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define tl tree[rt<<1]
#define tr tree[rt<<1|1]
void push_up(int rt)
{
if (tl==-1||tr==-1) tree[rt] = -1;
else if (tl!=tr) tree[rt] = -1;
}
void update(int L,int R,int c,int rt,int l,int r)
{
if (L<=l && r<=R){
tree[rt] = c;
return ;
}
if (tree[rt] > 0) tl = tr = tree[rt];
mid;
if (L<=m) update(L,R,c,lson);
if (R>m) update(L,R,c,rson);
push_up(rt);
}
PART 2:
dfs遍历树得到答案,用了差分标记
void dfs(int rt,int l,int r)
{
if (tree[rt] > 0){
sum[l] += tree[rt];
sum[r+1] -= tree[rt];
return ;
}
if (tree[rt] == -1){
mid;
dfs(lson);
dfs(rson);
}
}
主函数中:
dfs(1,1,MAXN);
for (int i=2;i<=MAXN;i++) sum[i] += sum[i-1];
int pre = 0;
for (int i=1;i<=MAXN;i++){
if (sum[i]!=pre){
ans[sum[i]-1]++;
pre = sum[i];
}
}
完整代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define mid int m = l+r>>1
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define tl tree[rt<<1]
#define tr tree[rt<<1|1]
using namespace std;
const int N = 8000+5;
int tree[N<<2],sum[N],ans[N];
int x[N],y[N],c[N];
void push_up(int rt)
{
if (tl==-1||tr==-1) tree[rt] = -1;
else if (tl!=tr) tree[rt] = -1;
}
void update(int L,int R,int c,int rt,int l,int r)
{
if (L<=l && r<=R){
tree[rt] = c;
return ;
}
if (tree[rt] > 0) tl = tr = tree[rt];
mid;
if (L<=m) update(L,R,c,lson);
if (R>m) update(L,R,c,rson);
push_up(rt);
}
void build(int rt,int l,int r)
{
if (l==r){
tree[rt] = 8002;
return ;
}
mid;
build(lson);
build(rson);
push_up(rt);
}
void dfs(int rt,int l,int r)
{
if (tree[rt] > 0){
sum[l] += tree[rt];
sum[r+1] -= tree[rt];
return ;
}
if (tree[rt] == -1){
mid;
dfs(lson);
dfs(rson);
}
}
int main()
{
int n;
while (~scanf("%d",&n)){
int MAXN = 1;
for (int i = 1;i<=n;i++){
scanf("%d %d %d",x+i,y+i,c+i);
x[i]++,c[i]++;
MAXN = max(MAXN,y[i]);
}
///init
build(1,1,MAXN);
//memset(tree,0,sizeof tree);
for (int i=0;i<=8000;i++) ans[i] = sum[i] = 0;
for (int i = 1;i<=n;i++){
if (x[i]<=y[i]) update(x[i],y[i],c[i],1,1,MAXN);
}
dfs(1,1,MAXN);
for (int i=2;i<=MAXN;i++) sum[i] += sum[i-1];
int pre = 0;
for (int i=1;i<=MAXN;i++){
if (sum[i]!=pre){
ans[sum[i]-1]++;
pre = sum[i];
}
}
for (int i=0;i<=8000;i++)
if (ans[i]) printf("%d %d\n",i,ans[i]);
printf("\n");
}
return 0;
}