CF1167G题解
CF1167G题解
简化题意:数轴上有 n 个不相交且处于坐标为非负整数的单位正方形,给 m 个询问点,求出把这个点右侧的数轴逆时针旋转至与左侧相交时的角度。
首先,碰撞时只能有以下两种情况:
1.正方形与数轴碰撞。
2.正方形与正方形碰撞。
对于第一种情况,我们通过画图就可以很好理解求法:

答案就是 \(\arctan \dfrac{1}{d}\) 。
对于第二中情况,我们可以证明,两个正方形只会在顶点上相交。

采用反证法,如果两个正方形的交点 A 在其中一个的边上(显然不可能都在边上),那么过 A 向其所在的边所对的正方形的底边作垂线,并连接 A 与旋转中心 M ,我们就可以通过角平分线的性质证明出 \(\triangle AMH\) 全等于 \(\triangle AMB\) ,因此 \(BM=HM\) ,而 B,M 都是整点,因此 \(BM\) 长为整数,所以 \(HM\) 长为整数,H 在整点上,这也就证明了交点一定在正方形顶点上。
那满足什么条件时才会在顶点上相交呢?

结合下图和上图我们可以推出,当 \(\left|d1-d2\right|\leqslant1\) 时两个正方形会相交在顶点上,这时答案为 \(2\times\arctan \dfrac{1}{\max(d1,d2)}\) 。

数学的部分结束了,我们就开始考虑做法。
对于情况一,我们可以通过双指针 \(O(n)\) 求出所有答案。但对于情况二,我们考虑到情况一的答案最小为 \(\arctan \dfrac{1}{3500}\) ,这时情况二里 \(\max(d1,d2)\) 为 \(7000\) ,也就是说要向两侧找最多 \(7000\) 个点,直接暴力找是 \(O(md)\) 的,过不了,但我们可以用 bitset 来维护每个询问点左右两侧 d 个点上是否有正方形,这样就可以把复杂度降到 \(O(\dfrac{nd}{w}+q)\) ,这样就可以通过此题。
#include<bits/stdc++.h>
#define ll long long
#define ld long double
using namespace std;
inline int read(){
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s;
}
const int N=200501;
const ld pi=acos(-1);//求π
int n,d,m,le,ri;
ll a[N],q[N];
bitset<7005>l,r,tmp;
ld work(int i,int j){
return atan((ld)i/(ld)j);
}
int main(){
// freopen("travel.in","r",stdin);
// freopen("travel.out","w",stdout);
n=read(),d=read();
for(int i=1;i<=n;i++)a[i]=read();
m=read();
for(int i=1;i<=m;i++)q[i]=read();
for(int i=1;i<=n&&a[i]<=q[1]+7000;i++){//处理第一个询问点前的情况
if(a[i]>=q[1])r.set(a[i]-q[1]);
else{
le=i+1;
if(a[i]>=q[1]-7001)l.set(q[1]-a[i]-1);
}
}
for(int i=1;i<=m;i++){
ld ans=0;
int pos=0;
if(l.test(0)||r.test(0))ans=pi/(ld)2.0;
else ans=work(1,min(l._Find_first(),r._Find_first()));
tmp=l&r;if(tmp.any())pos=tmp._Find_first(),ans=max(ans,pos?2*work(1,pos):pi);//d1=d2的情况
tmp=(l<<1)&r;if(tmp.any())pos=tmp._Find_first(),ans=max(ans,2*work(1,pos));
tmp=l&(r<<1);if(tmp.any())pos=tmp._Find_first(),ans=max(ans,2*work(1,pos));//|d1-d2|=1的情况
printf("%.15Lf\n",ans);
if(i==m)return 0;
l<<=(q[i+1]-q[i]),r>>=(q[i+1]-q[i]);
while(a[le]<q[i+1]){
if(a[le]>=q[i+1]-7001)l.set(q[i+1]-a[le]-1);
le++;
}
while(a[ri]<=q[i+1]+7000&&ri<=n){
if(a[ri]>=q[i+1])r.set(a[ri]-q[i+1]);
ri++;
}
}
}
CF1167G题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- MySQL-explain详解说明
1.Explain介绍 在日常工作中, 我们会有时会开慢查询去记录一些执行时间比较久的SQL语句, 找出这些SQL语句后我们常常会用explain这个命令来查看一个这些SQL语句的执行计划, 查看该S ...
- 【BOOK】【实例】【requests库+正则表达式】猫眼TOP100电影排名爬取
猫眼电影TOP100页面爬取 https://maoyan.com/board/4 ##猫眼电影TOP100爬取 import requests import re import json impor ...
- echarts 折柱表混合图(折线,柱状图,表格)
效果图如下: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- maven父子项目,由于pom文件中的<packaging>pom</packaging>导致报数据源配置错误
啊啊啊~~~ 又是踩坑的一天!!! 我在子模块中进行开发,然后子模块的pom文件中也写了<packaging>pom</packaging>导致报数据源配置错误.具体内容如下图 ...
- WebStore 破解
前提 你需要首先安装该软件,并下载补丁,不过这些已经为你打包好了. WebStore 2020.1 , jetbrains-agent.jar , resources_zh_CN_WebStorm_2 ...
- ESP8266开发(物联网)
使用开发板制作wifi干扰器https://www.jianshu.com/p/f064ca36ee92
- redis中获取区间数据及获取总条数
import redis REDIS_ITEMS_HOST: str = host REDIS_ITEMS_PASSWORD: str = pwd REDIS_ITEMS_DB: int = 4 #查 ...
- daimayuan第三课(哈希,堆)
1:哈希 建立:拉链法: a:数组 #include <bits/stdc++.h> using namespace std; const int md = 1e9; int h[1000 ...
- SpingBoot面试大汇总
1.什么是SpringBoot? 1)用来优化Spring应用的初始搭建以及开发过程,使用特定的方式来配置(properties和yml文件) 2)嵌入式的内置服务器tomcat无需部署war文件简化 ...
- Qt之新建界面动态库并使用
动态库的创建 动态库的使用 动态库的创建 //SharedLib_global.h #ifndef SHAREDLIB_GLOBAL_H #define SHAREDLIB_GLOBAL_H #inc ...