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 ...
随机推荐
- 使用struts2实现文件上传与下载功能
这个问题做了两天,在网上找了很多例子,但是还有一些功能没有实现,暂时先把代码贴出来,以后在做这方面的功能时在修改 文件上传: 一开始我在网上找到基于servlet+jsp环境写的文件上传,但是在将页面 ...
- C#4.0中的dynamic关键字和ExpandoObject对象
dynamic最大的特点我想莫过于在它的类型在运行时才确定,这也是它与往静态类型关键字的最大区别.如果你在你的代码操作中用到了dynamic关键字去定义一个变量时,那么这个变量在编译的时候编译器不会对 ...
- 01_8_session
01_8_session 1. session总结 1.1服务器的一块内存(存key-value) 1.2和客户端窗口对应(子窗口)(独一无二) 1.3客户端和服务器有对应的SessionID 1.4 ...
- 监测UITextField的变化
监测UITextField的变化可以为UIControlEventEditingChanged事件添加target. 我们有时候会需要用到这个需求:输入框输入文本超过xx长度,不再允许输入其他内容! ...
- Spring Boot 应用 快速发布到linux服务器的脚本代码示例
前提说明:spring boot 应用打包成jar包之后要部署到Linux服务器上面运行,我用的nohup java -jar 命令,但是代码更新之后重新部署的时候覆盖原来的项目,又要手动运行ps - ...
- SpringMVC 项目中引用其他 Module 中的方法
1. 将要引用的Module 引入项目中 2. 在主Module中添加依赖, 3. 被引用的类必须放在 Module 中/src/下的某个package中,否则引用不到(重要)
- 如何使用postman做接口测试
1.get请求传参 只要是get请求都可以在浏览器中直接发: 在访问地址后面拼 ?key=value&key=value 例如: 在浏览器中直接输入访问地址,后面直接拼需要传给服务器的参数 ...
- loc与iloc函数的使用
Pandas中loc和iloc函数用法详解(源码+实例) https://blog.csdn.net/w_weiying/article/details/81411257 Pandas中loc,il ...
- ASCII码表含义
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a.b.c.d这样的52个字母(包括大写)以及0.1等数字还有一些常用的符号(例如*.#. ...
- POJ - 2250 Compromise (LCS打印序列)
题意:给你两个单词序列,求出他们的最长公共子序列. 多组数据输入,单词序列长度<=100,单词长度<=30 因为所有组成LCS的单词都是通过 a[i] == b[j] 更新的. 打印序列的 ...