解题报告
题意:
一些海报,覆盖上去后还能看到几张。
思路:
第一道离散化的题。
离散化的意思就是区间压缩然后映射。
给你这么几个区间[1,300000],[3,5],[6,10],[4,9]
区间左右坐标排序完就是
1,3,4,5,6,9,10,300000;
1,2,3,4,5,6, 7 ,8;
我们能够把上面的区间映射成[1,8],[2,4],[5,7],[3,6];
这样就节省了非常多空间。
给线段染色, lz标记颜色。
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct node
{
int x,y;
} p[10100];
int zb[20100],_hash[10100],lz[100000],ans;
void push_down(int root )
{
if(lz[root])
{
lz[root*2]=lz[root*2+1]=lz[root];
lz[root]=0;
}
}
void update(int root,int l,int r,int ql,int qr,int v)
{
if(ql>r||qr<l)return;
if(ql<=l&&r<=qr)
{
lz[root]=v;
return;
}
push_down(root);
int mid=(l+r)/2;
update(root*2,l,mid,ql,qr,v);
update(root*2+1,mid+1,r,ql,qr,v);
}
void _q(int root,int l,int r)
{
if(lz[root])
{
if(!_hash[lz[root]])
ans++;
_hash[lz[root]]=1;
return ;
}
if(l==r)return;
int mid=(l+r)/2;
_q(root*2,l,mid);
_q(root*2+1,mid+1,r);
}
int main()
{
int t,i,j,n;
scanf("%d",&t);
while(t--)
{
ans=0;
memset(_hash,0,sizeof(_hash));
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
zb[i]=p[i].x;
zb[i+n]=p[i].y;
}
sort(zb,zb+n*2);
int m=unique(zb,zb+n*2)-zb;
for(i=0; i<n; i++)
{
int ql=lower_bound(zb,zb+m,p[i].x)-zb+1;
int qr=lower_bound(zb,zb+m,p[i].y)-zb+1;
update(1,1,m,ql,qr,i+1);
}
_q(1,1,m);
printf("%d\n",ans);
}
}
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 41877 | Accepted: 12199 |
Description
Input
Output

Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
POJ训练计划2528_Mayor's posters(线段树/成段更新+离散化)
原文:http://www.cnblogs.com/cynchanpin/p/7373744.html