影子的宽度
Posted rabbit1103
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了影子的宽度相关的知识,希望对你有一定的参考价值。
影子的宽度
问题描述
桌子上零散地放着若干个盒子,盒子都平行于墙。桌子的后方是一堵墙。如图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少?
输入格式
第1行:3个整数L,R,N。-100000 ≤L≤R≤ 100000,表示墙所在的区间;1≤N≤100000,表示盒子的个数 接下来N行,每行2个整数BL, BR,-100000 ≤BL≤BR≤ 100000,表示一个盒子的左、右端点
输出格式
第1行:1个整数W,表示影子的总宽度。
样例输入
Sample Input 1
0 7 2
1 2
4 5
Sample Input 2
-10 10 2
-5 2
-2 2
Sample Input 3
-10 10 3
-7 0
-4 9
-4 2
Sample Input 4
-100 100 3
-7 2
5 9
2 5
Sample Input 5
-50 50 4
-2 4
0 6
9 10
-5 30
样例输出
Sample Output 1
2
Sample Output 2
7
Sample Output 3
16
Sample Output 4
16
Sample Output 5
35
题解
用线段树维护左闭右开的区间 [l,r)影子的总宽度,标记flag表示这段区间是否全被影子覆盖。下传标记的时候,传完后不能置为0。
1 #include <cstdio> 2 const int maxn=100000; 3 struct node{ 4 int num; 5 bool lb,rb,flag; 6 }f[5000005]; 7 int n,L,R,s,t; 8 int max(int x,int y) 9 { 10 return x>y?x:y; 11 } 12 void pushdown(int l,int r,int id) 13 { 14 if (!f[id].flag) return; 15 int ls=id<<1,rs=ls|1,mid=(l+r)>>1; 16 f[ls].num=mid-l; 17 f[rs].num=r-mid; 18 f[ls].flag=f[rs].flag=1; 19 f[ls].lb=f[ls].rb=f[rs].lb=f[rs].rb=1; 20 // f[id].flag=0; // 不知道为什么写了这句会WA 21 return; 22 } 23 void modify(int l,int r,int id) // [ l , r ) 24 { 25 pushdown(l,r,id); 26 if (s<=l && r<=t) 27 { 28 f[id].num=r-l; 29 f[id].lb=f[id].rb=1; 30 f[id].flag=1; 31 return; 32 } 33 f[id].flag=0; 34 int ls=id<<1,rs=ls|1,mid=(l+r)>>1; 35 if (s<mid) modify(l,mid,ls); // 注意!!!由于是左闭右开区间,这里没有等号 36 if (t>mid) modify(mid,r,rs); 37 f[id].lb=f[ls].lb; 38 f[id].rb=f[rs].rb; 39 f[id].num=f[ls].num+f[rs].num; 40 // pushdown(l,mid,ls); 41 // pushdown(mid,r,rs); 42 return; 43 } 44 int main() 45 { 46 int i,j; 47 scanf("%d%d%d",&L,&R,&n); 48 L+=maxn; R+=maxn; 49 while (n--) 50 { 51 scanf("%d%d",&s,&t); 52 s+=maxn,t+=maxn; 53 modify(L,R,1); 54 } 55 printf("%d",f[1].num); 56 return 0; 57 }
以上是关于影子的宽度的主要内容,如果未能解决你的问题,请参考以下文章