Codeforces989E. A Trance of Nightfall
$n \leq 200$个平面上的点,$q \leq 200$次询问:重复操作$m \leq 10000$次,到达点$x$的概率最大是多少。操作:一开始选点$P$,不一定要是给定点,可以是平面上任一点。然后,选一条穿过给定点至少两个点且穿过$P$的直线$l$,若有多条,等概率选一条;选中一条后,把$P$点移动到这条直线上的某个初始给定点,若有多个等概率选。
以为是不可做几何题,其实挺好玩的
如果知道两个点之间一次性直接到达的概率$A(x,y)$,那么记$f(i,j)$为走$i$步到点$j$的概率,$f(i,j)=\sum_{k=1}^{n}A(i,k)f(i-1,k)$,是个矩阵乘法,可以快速幂优化。后面$m-1$步可以用矩阵算,那第一步应该怎么选初始点呢?可以发现,固定了终点,用矩阵乘法推出了$f(m,i)$后,每条直线的贡献是固定的,而如果我们选的$P$点在几个直线的交汇处,得到的便是这几条直线贡献的平均值,这不如直接选一条贡献最大的直线(这里的选是说,把点P放在这条线上),而这总是可以做到的。因此输出答案最大的一条直线的答案即可。
有个问题,如果每次询问都要快速幂一次,那不久$qn^3logn$了吗?别担心,$A^{2^i}$是可以预处理的,等会要做乘法的时候只需拿$f$和某些$A^{2^i}$乘就好了,而一个一维数组$f$和矩阵的乘法是$n^2$的,如此少一个$n$,可通过。
通过个鬼。直线运算精度误差坑了我一个半小时。。这里上一个标程无误差版的板子:
struct line {
// ax + by + c = 0
int a, b, c; line() : a(), b(), c() { }
line(const point &p, const point &q)
: a(p.y - q.y)
, b(q.x - p.x)
, c(q.y * p.x - q.x * p.y)
{
int g = gcd(gcd(a, b), c);
if (g != ) { a /= g; b /= g; c /= g; }
if (a < ) { a = -a; b = -b; c = -c; }
} inline bool contains(const point &p) {
return a * p.x + b * p.y + c == ;
} // For sorting & duplicate removing
inline bool operator < (const line &other) const {
return a != other.a ? a < other.a :
b != other.b ? b < other.b : c < other.c;
}
inline bool operator == (const line &other) const {
return a == other.a && b == other.b && c == other.c;
}
};
以及我改longdouble终于通过的辣鸡版本:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<math.h>
//#include<complex>
//#include<set>
//#include<queue>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define double long double
#define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n;
#define maxn 40011
#define maxm 40011
#define eps 1e-10
bool equ(double a,double b) {return fabs(a-b)<eps;}
bool neq(double a,double b) {return fabs(a-b)>eps;}
bool le(double a,double b) {return a-b<-eps;}
bool leq(double a,double b) {return a-b<eps;}
bool ge(double a,double b) {return a-b>eps;}
bool geq(double a,double b) {return a-b>-eps;} struct Point{int x,y;}p[maxn];
struct Line
{
double k,b;
void make(const Point &A,const Point &B)
{
if (A.x==B.x) {k=1e18; b=A.x; return;}
k=1.0*(A.y-B.y)/(A.x-B.x);
b=A.y-k*A.x;
}
bool operator < (const Line &l)
{
if (neq(l.k,k)) return le(k,l.k);
return le(b,l.b);
}
bool operator == (const Line &l) {return equ(l.k,k) && equ(l.b,b);}
bool operator != (const Line &l) {return !((*this)==l);}
}l[maxm]; int len=;
vector<int> vl[maxm],vp[maxn]; struct Mat
{
double a[][];
Mat() {memset(a,,sizeof(a));}
Mat operator * (const Mat &b)
{
Mat ans;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
for (int k=;k<=n;k++)
ans.a[i][j]+=a[i][k]*b.a[k][j];
return ans;
}
}base[]; double f[maxn],g[maxn];
void mul(double *f,Mat b)
{
memset(g,,sizeof(g));
for (int j=;j<=n;j++)
for (int k=;k<=n;k++)
g[j]+=f[k]*b.a[j][k];
for (int j=;j<=n;j++) f[j]=g[j];
} int main()
{
n=qread();
for (int i=;i<=n;i++) {p[i].x=qread(); p[i].y=qread();}
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
{
len++;
l[len].make(p[i],p[j]);
}
sort(l+,l++len);
l[].k=l[len+].k=-1e18; l[].b=l[len+].b=-1e18;
{
int j=;
for (int i=;i<=len;i++) if (l[i]!=l[i-]) l[++j]=l[i];
len=j;
} for (int i=;i<=n;i++)
for (int j=;j<=len;j++)
if ((neq(l[j].k,1e18) && equ(l[j].k*p[i].x+l[j].b,p[i].y))
|| (equ(l[j].k,1e18) && equ(p[i].x,l[j].b)))
vl[j].push_back(i),vp[i].push_back(j); for (int i=;i<=n;i++)
for (int j=,to=vp[i].size();j<to;j++)
{
int u=vp[i][j];
for (int k=,too=vl[u].size();k<too;k++)
{
int x=vl[u][k];
base[].a[i][x]+=1.0/(to*too);
}
} for (int i=;i<=;i++) base[i]=base[i-]*base[i-];
int lq=qread(),x,y;
while (lq--)
{
x=qread(); y=qread(); y--;
memset(f,,sizeof(f)); f[x]=;
for (int i=;i<=;i++) if ((y>>i)&) mul(f,base[i]);
double ans=;
for (int i=;i<=len;i++)
{
double tmp=;
for (int j=,to=vl[i].size();j<to;j++) tmp+=f[vl[i][j]];
ans=max(ans,tmp/vl[i].size());
}
cout<<ans<<endl;
}
return ;
}
Codeforces989E. A Trance of Nightfall的更多相关文章
- Codeforces Round #487 (Div. 2) E. A Trance of Nightfall (矩阵优化)
题意 有一个平面 , 给你 \(n\) 个点构成一个点集 \(S\) , 一开始可以选择一个平面上任意点 \(P\) . 存在一种操作 : 1 选择一条至少 通过 \(S\) 中任意两个点以及 \(P ...
- Codeforces 989E A Trance of Nightfall 矩阵快速幂+DP
题意:二维平面上右一点集$S$,共$n$个元素,开始位于平面上任意点$P$,$P$不一定属于$S$,每次操作为选一条至少包含$S$中两个元素和当前位置$P$的直线,每条直线选取概率相同,同一直线上每个 ...
- Sunset: Nightfall Vulnhub Walkthrough
靶机链接: https://www.vulnhub.com/entry/sunset-nightfall,355/ 主机扫描: ╰─ nmap -p- -A 10.10.202.162Starting ...
- 每日英语:Who Ruined The Humanities?
You've probably heard the baleful reports. The number of college students majoring in the humanities ...
- 《图解HTTP》阅读笔记
HTTP基础的简单理解 在了解HTTP协议之前,我们先了解下TCP/IP的参考模型,TCP/IP参考模型分为四层:应用层.传输层.网络层.链路层(数据链路层). 应用层:为不同的网络应用提供所需的服务 ...
- 现在开始(Do It Now)
现在开始(Do It Now) 很多年前读大学的时候,我决定制定一个计划挑战自己:只用三个学期完成其他人通常花费四年的课程,能否毕业.这篇文章(此文为翻译)详细的说明了我在成功实现该目标过程中的所有时 ...
- ural 1250. Sea Burial
1250. Sea Burial Time limit: 1.0 secondMemory limit: 64 MB There is Archipelago in the middle of a s ...
- Linux下编译内核配置选项简介
Code maturity level options代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完 ...
- (转)TCP注册端口号大全
分类: 网络与安全 cisco-sccp 2000/tcp Cisco SCCPcisco-sccp 2000/udp Cisco SCCp# Dan Wing <dwing&cisco ...
随机推荐
- SSH框架使用poi插件实现Excel的导入导出功能
采用POI生成excel结构 直接贴出代码 excel表格导出功能 action代码: struts.xml配置: 前台jsp代码:
- iOS 导航栏遮挡问题 --- iOS开发系列 ---项目中成长的知识七
不知大家有没有遇见过自己写的tableview被导航栏遮挡住的问题,反正我是遇见过! 因为在ios7以后所有的UIViewController创建后默认就是full Screen的,因此如果带导航栏的 ...
- C++ 学习笔记 开篇
从大一开始学习C语言,大学期间做了许多嵌入式的开发项目,毕业后从事嵌入式开发工作主要的开发语言也是C语言.虽然期间断断续续的学习过C++,做过QT.C#上位机但也只是在其他语言的外壳下使用C在开发,始 ...
- 【数位dp】bzoj3131: [Sdoi2013]淘金
思路比较自然,但我要是考场上写估计会写挂:好像被什么不得了的细节苟住了?…… Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1. ...
- python numpy复制array
numpy快速复制array 前段时间想到一个算法,需要实现array的自我复制,直接上代码,两种复制方式, 整体复制 a=[[10,10,50,50],[10,10,40,50]] np.tile( ...
- python入门学习笔记1:Python与C的简单区别
转载于:https://www.cnblogs.com/mlgjb/p/7892130.html 并做适当修改 一:简单比较 C语言 python 执行速度 快 慢 跨平台 不可以 可以 用途 操 ...
- Linux下open函数、read函数、write函数记录
open() #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> int open( cons ...
- Huawei比赛数据分析
如何评价2018年华为软件精英挑战赛赛题? https://www.zhihu.com/question/268448695 1.时间与时间戳之间的转换 https://blog.csdn.net/g ...
- 查找最小的k个元素 【微软面试100题 第五题】
题目要求: 输入n个整数,输出其中最小的k个. 例如:输入1,2,3,4,5,6,7,8这8个数字,则最小的4个数字为1,2,3,4. 参考资料:剑指offer第30题. 题目分析: 解法一: 用快排 ...
- Markdown,后缀MD
Markdown 算是一门新兴语言,现在 7-8 岁了吧.它设计的初衷就是让写字的人专注于写字,用纯文本简单的符号标记格式,最后再通过工具转换成鬼畜的 HTML/XHTML.如果你玩过 wikiped ...