这道题的大意就是求可以看到多少张没被覆盖的海报
5555我研究了很久才搞清楚离散化的线段树!!!!
题解:这是一道典型的线段树,但是因为数据量很大,所以需要离散化;其实他就是一个区间染色,最后统计被不同染色的区间有多少个!!!!
最后我感觉其离散化就是把数据处理一下,数据表示的本质不变。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define mx 10000
struct node
{
int le;
int ri;
int col;
}tree[mx*4];
/用于离散化的结构体
struct ss
{
int weizhi;
int point;
}san[mx*4];
int flag[mx*4];///用于标记颜色是否被访问过
void build(int id,int l,int r)
{
tree[id].le=l;
tree[id].ri=r;
tree[id].col=0;
if(l!=r)
{
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
}
void pushdown(int id)
{
if(tree[id].col)
{
tree[id*2+1].col=tree[id*2].col=tree[id].col;
tree[id].col=0;
}
}
void update(int id,int l,int r,int v)
{
if(l<=tree[id].le&&r>=tree[id].ri)
{
tree[id].col=v;
return ;
}
pushdown(id);
int mid=(tree[id].le+tree[id].ri)/2;
if(l<=mid)
update(id*2,l,r,v);
if(r>mid)
update(id*2+1,l,r,v);
//之所以不向上更新是因为我们的每个节点表示的是颜色.
}
int sum;
void ask(int id)
{
if(tree[id].col)
{
if(!flag[tree[id].col]) //颜色是否被访问
{
sum++;
flag[tree[id].col]=1;
}
}
else{
ask(id*2);
ask(id*2+1);
}
}
bool cmp(ss a1,ss a2)
{
return a1.point<a2.point;
}
int main()
{
int i,j,t,n;
int a[mx*4][2];
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d %d",&a[i][0],&a[i][1]);
san[i*2].point=a[i][0];
san[i*2+1].point=a[i][1];
san[i*2].weizhi=-(i+1);
san[i*2+1].weizhi=i+1;
}
sort(san,san+n*2,cmp);
int temp=san[0].point;
int cnt=1;
for(i=0;i<n*2;i++)
{
if(temp!=san[i].point)
{
cnt++;
temp=san[i].point;
}
if(san[i].weizhi<0)
{
a[-san[i].weizhi-1][0]=cnt;
}
else a[san[i].weizhi-1][1]=cnt;
}
离散化
/
build(1,1,cnt);
for(i=0;i<n;i++)
update(1,a[i][0],a[i][1],i+1);
memset(flag,0,sizeof(flag));
sum=0;
ask(1);
printf("%d\n",sum);
}
}
}