Mayor's posters (POJ-2528)
The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules:
- Every candidate can place exactly one poster on the wall.
- All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown).
- The wall is divided into segments and the width of each segment is one byte.
- Each poster must completely cover a contiguous number of wall segments.
They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections.
Your task is to find the number of visible posters when all the posters are placed given the information about posters' size, their place and order of placement on the electoral wall.
Input
The first line of input contains a number c giving the number of cases that follow. The first line of data for a single case contains number 1 <= n <= 10000. The subsequent n lines describe the posters in the order in which they were placed. The i-th line among the n lines contains two integer numbers l i and ri which are the number of the wall segment occupied by the left end and the right end of the i-th poster, respectively. We know that for each 1 <= i <= n, 1 <= l i <= ri <= 10000000. After the i-th poster is placed, it entirely covers all wall segments numbered l i, l i+1 ,... , ri.
Output
For each input data set print the number of visible posters after all the posters are placed.
The picture below illustrates the case of the sample input.
Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
题目翻译:
AB的Bytetown市民无法容忍市长竞选的候选人随心所欲地在各地张贴竞选海报。市议会最终决定建造一面张贴海报的选举墙,并引入以下规则:
每个候选人都可以在墙上贴一张海报。
所有海报的高度均等于墙的高度;海报的宽度可以是任意整数字节数(字节是字节敦长度的单位)。
墙被分成段,每段的宽度为一个字节。
每个海报必须完全覆盖连续的墙段。
他们建造了一堵10000000字节长的墙(这样就有足够的空间容纳所有候选人)。竞选活动重新开始时,候选人把他们的海报贴在墙上,海报的宽度相差很大。此外,候选人开始把他们的海报张贴在已经被其他海报占据的墙上。Bytetown的每个人都很好奇,谁的海报会在选举前的最后一天出现(全部或部分)。
你的任务是找出所有张贴在选举墙上的海报的大小、位置和排列顺序等信息后,可见的海报的数量。
输入
第一行输入包含一个数字c,它给出了后面的案例数量。单个案例的第一行数据包含数字1 <= n <= 10000。接下来的n行描述了海报的摆放顺序。n行中的第i行包含两个整数li和ri,分别为第i海报的左端和右端所占的墙体段数。我们知道对于每一个1 <= i <= n, 1 <= l i <= ri <= 10000000。第i张海报放置后,它完全覆盖了编号为li, li +1,…,国际扶轮。
输出
对于每个输入数据集,打印所有海报放置后可见的海报数量。
思路:
线段树,既是这个区间的懒惰标记值,也就第几张海报,到最后查询一次就行了,只有查询到这个区间的懒惰标记值不为0,就可以返回了,由于给出的墙太长,但是给你的海报上数就10000,所以你可以离散化。
数据离散化不会的可以看一下这篇文章:传送门
AC代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define PI 3.1415926
#define inf 0x3f3f3f3f
const int maxn=100010;
using namespace std;
int Sum[maxn<<2];
int A[maxn<<2];
int book[maxn<<2];
vector<int> v;
struct node
{
int a,b;
} S[maxn<<2];
void PushUp(int rt)
{
Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
}
void PushDown(int rt)
{
Sum[rt<<1]=Sum[rt<<1|1]=Sum[rt];
Sum[rt]=0;
}
void Build(int l,int r,int rt)
{
Sum[rt]=0;
if(l==r)
{
return;
}
int m=(l+r)>>1;
Build(l,m,rt<<1);
Build(m+1,r,rt<<1|1);
}
void Update(int x,int y,int k,int l,int r,int rt)
{
if(x<=l && r<=y)
{
Sum[rt]=k;
return;
}
if(Sum[rt])
PushDown(rt);
int m=(l+r)>>1;
if(x<=m)
Update(x,y,k,l,m,rt<<1);
if(m<y)
Update(x,y,k,m+1,r,rt<<1|1);
}
void Query(int l,int r,int rt)
{
if(l==r && Sum[rt]==0)
return;
if(Sum[rt])
{
book[Sum[rt]]=1;
return;
}
int m=(l+r)>>1;
Query(l,m,rt<<1);
Query(m+1,r,rt<<1|1);
}
int main()
{
int c,n;
int i,j;
scanf("%d",&c);
while(c--)
{
v.clear();
scanf("%d",&n);
int a,b;
memset(book,0,sizeof(book));
for(i=1; i<=n; i++)
{
scanf("%d%d",&S[i].a,&S[i].b);
v.push_back(S[i].a);
v.push_back(S[i].b);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
A[0]=1;
int k=1;
for(i=1; i<v.size(); i++)
{
if(v[i]==v[i]+1)
{
k++;
A[i]=k;
}
else
{
k++;
A[i]=k;
}
}
for(i = 1; i<=n; i++)
{
S[i].a=A[(lower_bound(v.begin(),v.end(),S[i].a)-v.begin())];
S[i].b=A[(lower_bound(v.begin(),v.end(),S[i].b)-v.begin())];
}
Build(1,v.size()<<1|10,1);
for(i=1; i<=n; i++)
Update(S[i].a,S[i].b,i,1,v.size()<<1|10,1);
Query(1,v.size()<<1|10,1);
int sum=0;
for(i=0;i<=n;i++)
{
if(book[i])
sum++;
}
printf("%d\n",sum);
}
return 0;
}