题意:给一段长度,在上面涂颜色,把最后能看见的颜色及此颜色出现了几段输出
线段树区间更新,查询的时候用一个结构体,此结构体存每个颜色最后出现的位置,以及已经出现的次数,当最后出现的位置和下一次出现的开头差一,则代表两段是连续的
注意题目要求是区间涂色,假如要求【0,2】涂色,线段树应该更新【0,1】区间,如果更新2,则【2,3】区间也被涂了色。
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <math.h>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
#include <set>
#include <list>
#include <iostream>
#define ll long long
#define ull unsigned long long
#define cls(x) memset(x,0,sizeof(x))
#define clslow(x) memset(x,-1,sizeof(x))
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e4+10;
const int mod=1e9+7;
int lazy[maxn<<2];
struct nn
{
int ed,num;
nn(){ed=-1;num=0;}
}col[maxn];
void Push_down(int rt)
{
if(lazy[rt]!=-1){
lazy[rt<<1]=lazy[rt];
lazy[rt<<1|1]=lazy[rt];
lazy[rt]=-1;
}
}
void Update(int L,int R,int l,int r,int rt,int c)
{
if(L<=l && r<=R)
{
lazy[rt]=c;
return;
}
Push_down(rt);
int mid=(l+r)>>1;
if(L<=mid)Update(L,R,l,mid,rt<<1,c);
if(R>mid)Update(L,R,mid+1,r,rt<<1|1,c);
}
void Query(int L,int R,int l,int r,int rt)
{
if(L<=l && r<=R && lazy[rt]>=0)
{
int c=lazy[rt];
if(col[c].ed==-1 || col[c].ed+1!=l){
col[c].num++;
}
col[c].ed=r;
return ;
}
if(l==r)return;
int mid=(l+r)>>1;
if(L<=mid)Query(L,R,l,mid,rt<<1);
if(R>mid)Query(L,R,mid+1,r,rt<<1|1);
}
int main()
{
int n;
while(~scanf("%d",&n)){
memset(lazy,-1,sizeof lazy);
for(int i=0;i<n;i++){
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
if(u==v)continue;
Update(u,v-1,0,8000,1,c);
}
Query(0,8000,0,8000,1);
for(int i=0;i<=8000;i++){
if(col[i].num>0)
printf("%d %d \n",i,col[i].num),
col[i].num=0,
col[i].ed=-1;
}
printf("\n");
}
return 0;
}