【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询
题目描述
输入
输出
样例输入
4
0 0 3 5
2 1 3 5
3 3 3 5
0 5 3 5
样例输出
1.833333333
题解
扫描线+二维树状数组区间修改区间查询
显然题目相当于:先给每个矩形内的权值+1,再查询每个矩形内的权值和即为任意选出两个矩形(可以相同,有顺序)的交面积的和,再减去每个矩形的面积(自己和自己)即得选出两个不同矩形的交面积之和。
那么我们把修改和询问差分成4个端点,就相当于统计每个询问拆出点的左下修改拆出点的贡献。使用扫描线维护。
注意到我们要做的是矩形加、矩形求和,可以使用 二维树状数组的区间修改区间查询 的方法,扫描线、一维树状数组方法类似。
最后除以 $n(n-1)$ 即可得到答案。
然而本题最恶心一点:本题爆long long!因此只能使用long double大法。由于最终答案只有 $10^{12}$ 级别,因此long double的精度是够的,不需要担心精度问题。
时间复杂度 $O(n\log n)$
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
using namespace std;
typedef long double ld;
int k;
struct bit
{
ld f[N << 2];
inline void add(int x , ld a)
{
int i;
for(i = x ; i <= k ; i += i & -i) f[i] += a;
}
inline ld ask(int x)
{
int i;
ld ans = 0;
for(i = x ; i ; i -= i & -i) ans += f[i];
return ans;
}
}A , B , C , D;
struct data
{
ld x;
int y , z , val;
bool operator<(const data &a)const {return x < a.x;}
}a[N << 1] , b[N << 1];
ld v[N << 2];
inline void modify(ld x , int y , int a)
{
A.add(y , a) , B.add(y , x * a) , C.add(y , v[y] * a) , D.add(y , x * v[y] * a);
}
inline ld query(ld x , int y)
{
return (x + 1) * (v[y] + 1) * A.ask(y) - (v[y] + 1) * B.ask(y) - (x + 1) * C.ask(y) + D.ask(y);
}
int main()
{
int n , i , p = 1;
ld xi , yi , ai , bi , ans = 0 , sum;
scanf("%d" , &n) , sum = (ld)n * (n - 1);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%Lf%Lf%Lf%Lf" , &xi , &yi , &ai , &bi) , ans -= ai * bi;
a[i].x = xi , a[i].y = yi , a[i].z = yi + bi , a[i].val = 1;
b[i].x = xi - 1 , b[i].y = yi - 1 , b[i].z = yi + bi - 1 , b[i].val = -1;
a[i + n].x = xi + ai , a[i + n].y = yi , a[i + n].z = yi + bi , a[i + n].val = -1;
b[i + n].x = xi + ai - 1 , b[i + n].y = yi - 1 , b[i + n].z = yi + bi - 1 , b[i + n].val = 1;
v[++k] = yi , v[++k] = yi + bi , v[++k] = yi - 1 , v[++k] = yi + bi - 1;
}
sort(v + 1 , v + k + 1) , k = unique(v + 1 , v + k + 1) - v;
for(i = 1 ; i <= 2 * n ; i ++ )
{
a[i].y = lower_bound(v + 1 , v + k + 1 , a[i].y) - v;
a[i].z = lower_bound(v + 1 , v + k + 1 , a[i].z) - v;
b[i].y = lower_bound(v + 1 , v + k + 1 , b[i].y) - v;
b[i].z = lower_bound(v + 1 , v + k + 1 , b[i].z) - v;
}
sort(a + 1 , a + 2 * n + 1) , sort(b + 1 , b + 2 * n + 1);
for(i = 1 ; i <= 2 * n ; i ++ )
{
while(p <= 2 * n && a[p].x <= b[i].x) modify(a[p].x , a[p].y , a[p].val) , modify(a[p].x , a[p].z , -a[p].val) , p ++ ;
ans += b[i].val * (query(b[i].x , b[i].z) - query(b[i].x , b[i].y));
}
printf("%.9Lf\n" , ans / sum);
return 0;
}
【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询的更多相关文章
- 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询
题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...
- POJ2155 Matrix(二维树状数组||区间修改单点查询)
Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row an ...
- poj 2155 (二维树状数组 区间修改 求某点值)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 33682 Accepted: 12194 Descript ...
- 【poj2155】Matrix(二维树状数组区间更新+单点查询)
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
- TZOJ 2725 See you~(二维树状数组单点更新区间查询)
描述 Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algo ...
- hdu 2642二维树状数组 单点更新区间查询 模板题
二维树状数组 单点更新区间查询 模板 从零开始借鉴http://www.2cto.com/kf/201307/227488.html #include<stdio.h> #include& ...
- 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询
题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...
- 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询
题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...
- hdu 2642 二维树状数组 单点更新区间查询 模板水题
Stars Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others) Total Subm ...
随机推荐
- rsync + inotify 数据实时同步
一.rsync介绍 rsync英文全称为Remote synchronization,从软件的名称就可以看出来,Rsync具有可是本地和远程两台主机之间的数据快速复制同步镜像.远程备份的功能,这个功能 ...
- Selenium2+python自动化-操作浏览器基本方法
前言 从这篇开始,正式学习selenium的webdriver框架.我们平常说的 selenium自动化,其实它并不是类似于QTP之类的有GUI界面的可视化工具,我们要学的是webdriver框架的A ...
- Django——POST请求及Action触发事件
添加网页login,将类型置为post,并添加action page,也就是之前写好的页面 添加page网页的views函数,要求获取post指令,如果username及password均正确则跳转到 ...
- JUC——TimeUnit工具类(二)
TimeUnit工具类 在java.util.concurrent开发包里面提供有一个TimeUnit类,这个类单独看它的描述是一个时间单元类.该类是一个枚举类,这也是juc开包里面唯一的一个枚举类. ...
- nginx启动、停止重启
启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /us ...
- Scrum立会报告+燃尽图(十月二十四日总第十五次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
- “Hello World!”团队第十三次会议
今天是我们团队“Hello World!”团队召开的第十三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 2 ...
- 【线段树求区间第一个不大于val的值】Lpl and Energy-saving Lamps
https://nanti.jisuanke.com/t/30996 线段树维护区间最小值,查询的时候优先向左走,如果左边已经找到了,就不用再往右了. 一个房间装满则把权值标记为INF,模拟一遍,注意 ...
- HDU 5154 Harry and Magical Computer 有向图判环
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5154 题解: 有向图判环. 1.用dfs,正在访问的节点标记为-1,已经访问过的节点标记为1,没有访 ...
- windows+ubuntu时间修改问题
只需要在ubuntu系统数输入一行指令即可 timedatectl set-local-rtc 1 --adjust-system-clock