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 ...
随机推荐
- 作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
- iOS 解决ipv6问题
解决ipv6的方法有很多种,由于现在国内的网络运营商还在使用ipv4的网络环境,所以appstore应用不可能大范围去修改自己的服务器, 而且国内的云服务器几乎没有ipv6地址. 这里附上苹果开发平台 ...
- python入门:最基本的用户登录
#! usr/bin/env python # -*- coding: utf-8 -*- #最基本的用户登录 import getpass usre = input("username:& ...
- 数字内置方法详解(int/long/float/complex)
一.常用方法 1.1.int 以下是Python2.7的int内置函数: 序号 函数名 作用 举例 1 int.bit_length() 二进制存储这个整数至少需要多少bit(位). >> ...
- python3通过Beautif和XPath分别爬取“小猪短租-北京”租房信息,并对比时间效率(附源代码)
爬虫思路分析: 1. 观察小猪短租(北京)的网页 首页:http://www.xiaozhu.com/?utm_source=baidu&utm_medium=cpc&utm_term ...
- IAR单片机启动文件与程序入口
最近在做TI单片机TM4C123GE6PZ的BootLoader,需要对启动文件做出修改,折腾了半宿,弄得事实而非. IAR默认提供了单片机的启动文件,cstart.s或者其他cstartxxx.s, ...
- URAL - 2065 Different Sums (思维题)
题意: 给n和k,让你用不小于 k 个不同的数字构成一个长度为n的序列,使得序列中不同的区间和的数目最小. n,k<=500 k-1个数填一些数字的一正一负,这样有些区间和为0. 剩下的都填0. ...
- jenkins执行构建并查看结果
继完成构建项目配置http://www.cnblogs.com/yajing-zh/p/5111060.html后,则要执行构建. 回到jenkins主页之后,我们看到一个新建的项目显示出来: 点击进 ...
- 由浅入深学习PBR的原理和实现
目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...
- loj2013 「SCOI2016」幸运数字
点分治+线性基 (为了这六个字窝调了一下午一晚上QAQ #include <iostream> #include <cstring> #include <cstdio&g ...