bzoj5029 贴小广告
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
1 4
2 6
8 10
3 4
7 10
Sample Output
4
正解:线段树。
线段树区间覆盖傻逼题。
$upd$:其实这个做法是错的,不过懒得改了。。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define N (100010) 6 #define ls (x<<1) 7 #define rs (x<<1|1) 8 9 using namespace std; 10 11 struct data{ int l,r; }q[N]; 12 13 int sum[N<<2],hsh[N<<1],a[N<<1],vis[N<<1],n,tot,ans; 14 15 il int gi(){ 16 RG int x=0,q=1; RG char ch=getchar(); 17 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 18 if (ch=='-') q=-1,ch=getchar(); 19 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 20 return q*x; 21 } 22 23 il void pushdown(RG int x){ sum[ls]=sum[rs]=sum[x],sum[x]=0; return; } 24 25 il void update(RG int x,RG int l,RG int r,RG int xl,RG int xr,RG int v){ 26 if (xl<=l && r<=xr){ sum[x]=v; return; } 27 if (sum[x]) pushdown(x); RG int mid=(l+r)>>1; 28 if (xr<=mid) update(ls,l,mid,xl,xr,v); 29 else if (xl>mid) update(rs,mid+1,r,xl,xr,v); 30 else update(ls,l,mid,xl,mid,v),update(rs,mid+1,r,mid+1,xr,v); 31 } 32 33 il void query(RG int x,RG int l,RG int r){ 34 if (l==r){ a[l]=sum[x]; return; } 35 if (sum[x]) pushdown(x); RG int mid=(l+r)>>1; 36 query(ls,l,mid),query(rs,mid+1,r); return; 37 } 38 39 int main(){ 40 #ifndef ONLINE_JUDGE 41 freopen("advertising.in","r",stdin); 42 freopen("advertising.out","w",stdout); 43 #endif 44 n=gi(); 45 for (RG int i=1;i<=n;++i) q[i].l=gi(),q[i].r=gi(),hsh[++tot]=q[i].l,hsh[++tot]=q[i].r; 46 sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1; 47 for (RG int i=1;i<=n;++i){ 48 q[i].l=lower_bound(hsh+1,hsh+tot+1,q[i].l)-hsh; 49 q[i].r=lower_bound(hsh+1,hsh+tot+1,q[i].r)-hsh; 50 update(1,1,tot,q[i].l,q[i].r,i); 51 } 52 query(1,1,tot); for (RG int i=1;i<=tot;++i) ans+=!vis[a[i]],vis[a[i]]=1; 53 printf("%d\n",ans); return 0; 54 }