标签:nod follow wal sdi alt can describe ber include
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 64939 | Accepted: 18770 |
Description
Input
Output
Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
题意:
N个人(1<=N<=10000)依次贴N张等高的海报,
给出每张海报的左端点,右端点li,ri(1<=li<=ri<=10000000)。
后面的海报可能会把前面的海报盖住。
问最后能看见几张海报。
题解:
一个比较明显的区间染色问题。
暴力肯定会TLE+爆内存,没有问题吧。
对我这种蒟蒻来说好像只会用刚学的线段树。
但是端点范围太大,直接开数组明显不可行。
所以还要离散化一下。
所谓的离散化,在我理解看来
就是将一个很大的区间映射成一个很小的区间,
而不改变原有的覆盖关系。
但是对于这道题而言,简单的离散化可能会出现错误。
比如说:
例子一:[1,10][1,4][5,10]
例子二:[1,10][1,4][6,10]
它们普通离散化后都变成了[1,4][1,2][3,4]。
线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被覆盖掉了呢?
例子一是被覆盖掉了,而例子二没有被覆盖。
解决的办法,就是在距离大于1的两个相邻节点间插入一个点,保证准确性。
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; struct node{int l,r;}a[100001]; //节点信息 int N,ans; int c[400001]; //区间每个点的颜色 bool vis[100001]; //记录颜色访问信息 int x[100001]; //离散化后的区间 inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; return x*f; } void cover(int num){ if(c[num]!=-1){ c[num<<1]=c[num<<1|1]=c[num]; c[num]=-1; } } void update(int L,int R,int col,int l,int r,int num){ //如果这个点在需要染色的区间内,直接更新并且返回 if(l>=L && r<=R){ c[num]=col; return; } cover(num); //更新 int mid=(l+r)>>1; if(L<=mid) update(L,R,col,l,mid,num<<1); //更新左儿子 if(R>mid) update(L,R,col,mid+1,r,num<<1|1); //更新右儿子 } void query(int l,int r,int num){ //累加未出现的颜色 if(c[num]!=-1){ if(!vis[c[num]]) ans++; vis[c[num]]=1; return; } if(l==r) return; //如果到了叶子则返回 int mid=(l+r)>>1; query(l,mid,num<<1); //统计左儿子 query(mid+1,r,num<<1|1); //统计右儿子 } int main(){ int T=read(); while(T--){ memset(c,-1,sizeof(c)); memset(vis,0,sizeof(vis)); N=read();ans=0; int p=0; //输入点数 int q=1; //离散化后点数 for(int i=0;i<N;i++){ a[i].l=read();a[i].r=read(); x[p++]=a[i].l;x[p++]=a[i].r; } sort(x,x+p); //去重操作 for(int i=1;i<p;i++) if(x[i]!=x[i-1]) x[q++]=x[i]; //离散化操作 for(int i=q-1;i>=1;i--) if(x[i]>x[i-1]+1) x[q++]=x[i-1]+1; sort(x,x+q); //染色操作 for(int i=0;i<N;i++){ int l=lower_bound(x,x+q,a[i].l)-x; int r=lower_bound(x,x+q,a[i].r)-x; update(l,r,i,0,q,1); } //统计操作 query(0,q,1); printf("%d\n",ans); } return 0; }
【线段树+离散化】POJ2528 Mayor's posters
标签:nod follow wal sdi alt can describe ber include
原文地址:http://www.cnblogs.com/YSFAC/p/7143135.html