【bzoj5029】贴小广告

来源:互联网 发布:明基显示器调节软件 编辑:程序博客网 时间:2024/04/29 13:10

Description

现在有一堵墙,墙上分为若干个单元。接下来会来n个人在墙上贴小广告。每次每个人选择墙上连续一段的单元贴
上自己公司与众不同的小广告。因为小广告可能会出现被覆盖的情况,由于公司之间存在竞争,后贴广告的人想让
别人看不见前面公司的广告,所以会将前面的广告完全覆盖。因此对于墙上的某个单元上贴的小广告中只有贴的最
晚的能被看见。现在想要知道n个人依次贴完后,墙上共能看到多少种小广告?
Input

输入文件第一行有一个整数 n。
接下来 n 行每行 2 个整数 li、ri,表示这个人在第li个单元到第ri个单元贴了小广告。
1 <= n,m <= 10^5 , 1<=li<=ri<=10^7
Output

输出所有人贴完后墙上能看到多少种小广告?
Sample Input

5

1 4

2 6

8 10

3 4

7 10
Sample Output

4

题解
对于区间覆盖问题,采用线段树维护,根据最终结果计算答案,需离散化。

代码

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<set>#include<ctime>#include<vector>#include<cmath>#include<algorithm>#include<map>#include<queue>#define mod 20101009#define ll long long #define N 10000005 using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int tot,n,ans,t[400005],b[100005][2];struct node{int x,l,r,id;}a[200005];bool vis[100005];bool cmp(node a,node b){return a.x<b.x;}void pushdown(int k,int l,int r){    int c=t[k];t[k]=0;    if (l==r) return;    t[k<<1]=t[k<<1|1]=c;}void modify(int k,int l,int r,int x,int y,int z){    if (l==x&&r==y){t[k]=z;return;}    if (t[k]) pushdown(k,l,r);    int mid=(l+r)>>1;    if (y<=mid) modify(k<<1,l,mid,x,y,z);    else if (x>mid) modify(k<<1|1,mid+1,r,x,y,z);    else modify(k<<1,l,mid,x,mid,z),modify(k<<1|1,mid+1,r,mid+1,y,z);}void find(int k,int l,int r){    if (t[k])    {        if (!vis[t[k]]) ans++;        vis[t[k]]=1;        return;    }    if (l==r) return;    int mid=(l+r)>>1;    find(k<<1,l,mid);find(k<<1|1,mid+1,r);}int main(){    n=read();    for (int i=1;i<=n;i++)    {        a[(i<<1)-1].x=read();a[i<<1].x=read();        a[(i<<1)-1].l=1;a[i<<1].r=1;        a[(i<<1)-1].id=i;a[i<<1].id=i;    }    sort(a+1,a+(n<<1)+1,cmp);    for (int i=1;i<=n<<1;i++)    {        int tmp=(a[i].r==1);        if (a[i].x!=a[i-1].x) tot++;        b[a[i].id][tmp]=tot;    }    for (int i=1;i<=n;i++) modify(1,1,tot,b[i][0],b[i][1],i);    find(1,1,tot);    printf("%d",ans);    return 0;}
原创粉丝点击