【bzoj4418】[Shoi2013]扇形面积并 扫描线+线段树
2017-12-09 10:29
531 查看
题目描述
给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖。
输入
第一行是三个整数n,m,k。n代表同心扇形的个数,m用来等分 [-π,π]的弧度。
从第二行开始的n行,每行三个整数r,a1,a2。描述了一个圆心在原点的扇形,半径为r,圆心角是从弧度πa1/m到πa2/m,a1可能大于a2,逆时针扫过的区域为该扇形面积。
输出
输出一个整数ans,至少被K个扇形所覆盖的总面积等于π/2m×ans
保证答案不超过2^63-1
样例输入
【输入样例1】
3 8 2
1 -8 8
3 -7 3
5 -5 5
【输入样例2】
2 4 1
4 4 2
1 -4 4
样例输出
【输出样例1】
76
【输出样例2】
98
题解
扫描线+线段树
把每个扇形拆成:a1时刻加入扇形,a2时刻删除扇形。
那么把所有这样的边放到一起,按照出现位置排序。
然后问题转化为:前缀+1,前缀-1,查询值大于等于k的位置个数。容易发现数值是单调的,因此可以使用线段树维护修改,然后在线段树上二分解决问题。具体实现上,可以使用差分带点修改来代替区间修改。
时间复杂度 $O(n\log n)$
注意一下a1>a2时要拆成两个扇形(a1~m、-m~a2)解决。
给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖。
输入
第一行是三个整数n,m,k。n代表同心扇形的个数,m用来等分 [-π,π]的弧度。
从第二行开始的n行,每行三个整数r,a1,a2。描述了一个圆心在原点的扇形,半径为r,圆心角是从弧度πa1/m到πa2/m,a1可能大于a2,逆时针扫过的区域为该扇形面积。
输出
输出一个整数ans,至少被K个扇形所覆盖的总面积等于π/2m×ans
保证答案不超过2^63-1
样例输入
【输入样例1】
3 8 2
1 -8 8
3 -7 3
5 -5 5
【输入样例2】
2 4 1
4 4 2
1 -4 4
样例输出
【输出样例1】
76
【输出样例2】
98
题解
扫描线+线段树
把每个扇形拆成:a1时刻加入扇形,a2时刻删除扇形。
那么把所有这样的边放到一起,按照出现位置排序。
然后问题转化为:前缀+1,前缀-1,查询值大于等于k的位置个数。容易发现数值是单调的,因此可以使用线段树维护修改,然后在线段树上二分解决问题。具体实现上,可以使用差分带点修改来代替区间修改。
时间复杂度 $O(n\log n)$
注意一下a1>a2时要拆成两个扇形(a1~m、-m~a2)解决。
#include <cstdio> #include <algorithm> #define N 100010 #define lson l , mid , x << 1 #define rson mid + 1 , r , x << 1 | 1 using namespace std; struct data { int p , c , v; data() {} data(int P , int C , int V) {p = P , c = C , v = V;} bool operator<(const data &a)const {return p < a.p;} }q[N << 2]; int sum[N << 2] , tot; void update(int p , int a , int l , int r , int x) { sum[x] += a; if(l == r) return; int mid = (l + r) >> 1; if(p <= mid) update(p , a , lson); else update(p , a , rson); } int query(int k , int l , int r , int x) { if(l == r) return l; int mid = (l + r) >> 1; if(k < sum[x << 1]) return query(k , lson); else return query(k - sum[x << 1] , rson); } int main() { int n , m , k , i , a , b , r , last = 0 , now = 0; long long ans = 0; scanf("%d%d%d" , &n , &m , &k); for(i = 1 ; i <= n ; i ++ ) { scanf("%d%d%d" , &r , &a , &b); if(a <= b) q[++tot] = data(a , r , 1) , q[++tot] = data(b , r , -1); else q[++tot] = data(-m , r , 1) , q[++tot] = data(b , r , -1) , q[++tot] = data(a , r , 1) , q[++tot] = data(m , r , -1); } sort(q + 1 , q + tot + 1); for(i = 1 ; i <= tot ; i ++ ) { r = query(now - k , 1 , 100001 , 1) - 1 , ans += 1ll * r * r * (q[i].p - last); now += q[i].v , update(q[i].c + 1 , q[i].v , 1 , 100001 , 1) , last = q[i].p; } printf("%lld\n" , ans); return 0; }
相关文章推荐
- [BZOJ]4418: [Shoi2013]扇形面积并 线段树
- 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树
- bzoj 4418: [Shoi2013]扇形面积并
- 4418: [Shoi2013]扇形面积并|二分答案|树状数组
- 4418: [Shoi2013]扇形面积并|二分答案|树状数组
- BZOJ 4415 [Shoi2013]发牌【线段树
- BZOJ_P4415 [SHOI2013]发牌(线段树)
- bzoj4418 [Shoi2013]扇形面积并
- BZOJ4415 SHOI2013发牌(线段树)
- BZOJ1018 SHOI2008堵塞的交通(线段树)
- BZOJ 4419 [Shoi2013]发微博 - set
- hdu 1255 覆盖的面积(线段树+扫描线——面积交)
- [BZOJ]3110: [Zjoi2013]K大数查询 整体二分+线段树
- 【bzoj1018】[SHOI2008]堵塞的交通traffic 线段树区间合并+STL-set
- [BZOJ1818][Cqoi2010]内部白点(扫描线+线段树)
- hdu 1255 覆盖的面积 (线段树,离散化+扫描线)
- [poj1151]Atlantis矩形面积求交(扫描线+线段树)
- 【SHOI2013】【BZOJ4415】发牌
- bzoj 4869: [Shoi2017]相逢是问候 数论+线段树
- 【BZOJ4597】[Shoi2016]随机序列 线段树