ZJOI 2014 星系调查(推导)
题意
思路
说白了就是一条路径上有 \(n\) 个二维坐标,求一条直线使得所有点到此直线的距离和最小。
设这条直线为 \(y=kx+b\) ,距离和为 \(\delta\)。
\]
\]
由于 \(k,b\) 的取值互不影响,我们先假设 \(k\) 是一个常量,变形如下
\]
发现就是一个关于 \(b\) 的二次方程,开口朝上,顶点处取最小值,即
\]
设 \(\displaystyle\bar x={\sum x_i\over n},\displaystyle\bar y={\sum y_i\over n}\)
得出 \(b=\bar y-k\bar x\)
代入并化简成关于 \(k\) 的式子得到
\]
令
A&=\sum x_i^2-2\bar x\sum x_i+n\bar x^2\\
&=\sum x_i^2-{(\sum x_i)^2\over n}\\
B&=-2\sum x_iy_i+2\bar y \sum x_i+2\bar x\sum y_i-2n\bar x\bar y\\
&=-2\sum x_iy_i+2{\sum x_i\sum y_i\over n}\\
C&=\sum y_i^2-2\bar y\sum y_i+n\bar y^2\\
&=\sum y_i^2-{(\sum y_i)^2\over n}
\end{array}
\]
那么
\]
把 \(k\) 当作主元化简得
\]
这个二次方程的 \(\Delta\) 为 \(B^2-4(A-\delta)(C-\delta)\)
-4\delta ^2+4(A+C)\delta-4AC+B^2 \ge 0
\]
解得 \(\displaystyle\delta={A+C\pm \sqrt{A^2-2AC+B^2+C^2}\over 2}\)
根号前取负号即可达到最小值.
所以维护六元组 \((\sum x_i,\sum y_i,\sum x_i^2,\sum y_i^2,\sum x_iy_i,\sum1)\) 即可求出 \(A,B,C\) ,求出 \(\delta\) 的最小值。
树的情况只用维护到根路径上的信息即可。
基环树的情况类似,断开一条环边,再枚举可行路径(至多两条)即可。
代码
#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
template<typename T,typename _T>inline bool chk_min(T &x,const _T y){return y<x?x=y,1:0;}
template<typename T,typename _T>inline bool chk_max(T &x,const _T y){return x<y?x=y,1:0;}
typedef long long ll;
const int N=(int)1e5+5;
template<const int maxn,const int maxm,typename T>struct Linked_list
{
int head[maxn],nxt[maxm],tot;T to[maxm];
Linked_list(){clear();}
T &operator [](const int x){return to[x];}
void clear(){memset(head,-1,sizeof(head)),tot=0;}
void add(int u,T v){to[++tot]=v,nxt[tot]=head[u],head[u]=tot;}
#define EOR(i,G,u) for(int i=G.head[u];~i;i=G.nxt[i])
};
struct DisjointSet
{
int fa[N];
void init(int n){FOR(i,1,n)fa[i]=i;}
int get_fa(int x){return x==fa[x]?x:fa[x]=get_fa(fa[x]);}
void merge(int x,int y)
{
x=get_fa(x),y=get_fa(y);
if(x==y)return;
fa[x]=y;
}
};
struct hexa
{
int a,b,c,d,e,f;
hexa(int _a=0,int _b=0,int _c=0,int _d=0,int _e=0,int _f=0)
{
a=_a,b=_b,c=_c,d=_d,e=_e,f=_f;
}
hexa operator +(const hexa &_)const
{
return hexa(a+_.a,b+_.b,c+_.c,d+_.d,e+_.e,f+_.f);
}
hexa operator -(const hexa &_)const
{
return hexa(a-_.a,b-_.b,c-_.c,d-_.d,e-_.e,f-_.f);
}
hexa add(int x,int y)
{
return hexa(a+x,b+y,c+x*x,d+y*y,e+x*y,f+1);
}
double solve()
{
double A=c-1.0*a*a/f,B=-2*e+2.0*a*b/f,C=d-1.0*b*b/f;
return (A+C-sqrt(A*A-2*A*C+B*B+C*C))/2;
}
};
hexa sum[N];
DisjointSet D;
Linked_list<N,N<<1,int>G;
int dep[N],fa[N],sz[N],son[N],top[N];
int X[N],Y[N];
int n,m,q;
int U,V;
void dfs(int u,int f,int d)
{
dep[u]=d,fa[u]=f,sz[u]=1,son[u]=0;
sum[u]=sum[f].add(X[u],Y[u]);
EOR(i,G,u)
{
int v=G[i];
if(v==f)continue;
dfs(v,u,d+1);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v;
}
}
void hld(int u,int f,int tp)
{
top[u]=tp;
if(son[u])hld(son[u],u,tp);
EOR(i,G,u)
{
int v=G[i];
if(v==f||v==son[u])continue;
hld(v,u,v);
}
}
int get_lca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])std::swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int get_dis(int x,int y)
{
return dep[x]+dep[y]-2*dep[get_lca(x,y)];
}
hexa get_val(int x,int y)
{
int lca=get_lca(x,y);
return (sum[x]-sum[lca]+sum[y]-sum[lca]).add(X[lca],Y[lca]);
}
bool intersect(int a,int b,int c,int d)
{
int lca1=get_lca(a,b),lca2=get_lca(c,d);
return get_dis(a,lca2)+get_dis(lca2,b)==get_dis(a,b)||
get_dis(c,lca1)+get_dis(lca1,d)==get_dis(c,d);
}
int main()
{
scanf("%d%d",&n,&m);
FOR(i,1,n)scanf("%d%d",&X[i],&Y[i]);
D.init(n);
FOR(i,1,m)
{
int u,v;
scanf("%d%d",&u,&v);
if(D.get_fa(u)==D.get_fa(v))U=u,V=v;
else
{
G.add(u,v),G.add(v,u);
D.merge(u,v);
}
}
dfs(1,0,1);
hld(1,0,1);
scanf("%d",&q);
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
if(n==m-1)printf("%.5lf\n",get_val(x,y).solve());
else
{
double res=get_val(x,y).solve();
if(!intersect(x,U,y,V))chk_min(res,(get_val(x,U)+get_val(y,V)).solve());
if(!intersect(x,V,y,U))chk_min(res,(get_val(x,V)+get_val(y,U)).solve());
printf("%.5lf\n",res);
}
}
return 0;
}
ZJOI 2014 星系调查(推导)的更多相关文章
- bzoj 3528 [ZJOI2014] 星系调查 题解
[原题] 星系调查 [问题描写叙述] 银河历59451年.在银河系有许很多多已被人类殖民的星系.如果想要在行 星系间往来,大家一般使用连接两个行星系的跳跃星门. 一个跳跃星门能够把 物质在它所连接的 ...
- 「ZJOI2014」星系调查
「ZJOI2014」星系调查 本题核心在于快速求XPs 的线性假设相斥度. 点\((x1,y1)\)到直线\(y=kx+b\)的距离的平方为\(\displaystyle {(kx1+b-y1)^2} ...
- bzoj 3528: [Zjoi2014]星系调查
Description 银河历59451年,在银河系有许许多多已被人类殖民的星系.如果想要在行 星系间往来,大家一般使用连接两个行星系的跳跃星门. 一个跳跃星门可以把 物质在它所连接的两个行星系中互 ...
- 【BZOJ 3527】【ZJOI 2014】力
代换一下变成多项式卷积,这里是的答案是两个卷积相减,FFT求一下两个卷积就可以啦 详细的题解:http://www.cnblogs.com/iwtwiioi/p/4126284.html #inclu ...
- [ZJOI 2014]力
Description 给出n个数qi,给出Fj的定义如下: $$F_j = \sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{i>j}\frac{q_i ...
- 解题:ZJOI 2014 力
题面 事实说明只会FFT板子是没有用的,还要把式子推成能用FFT/转化一下卷积的方式 虽然这个题不算难的多项式卷积 稍微化简一下可以发现实际是$q_i$和$\frac{1}{(i-j)^2}$在卷,然 ...
- BZOJ3528: [Zjoi2014]星系调查
唉,看到这题直接想起自己的Day1,还是挺难受的,挺傻一题考试的时候怎么就没弄出来呢…… 这两天CP让我给他写个题解,弄了不是很久就把这个题给弄出来了,真不知道考试的时候在干嘛. 明天就出发去北京了, ...
- bzoj 3528 [Zjoi2014]星系调查【树链剖分+数学】
参考:https://www.cnblogs.com/zhuohan123/p/3698852.html 首先,根据点到直线距离公式 \[ d=\frac{kx_0-y_0+b}{\sqrt{k^{2 ...
- 【ZJOI 2014】力
Problem Description 给出 \(n\) 个数 \(q_i\),给出 \(F_j\) 的定义如下: \[F_j=\sum_{i<j} \frac{q_iq_j}{(i-j)^2} ...
随机推荐
- 2019/4/22 拓扑排序的高效写法. 模板题HDU1285:确定比赛名次
传送门 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现 ...
- mysql-8.0.13在windows上的部署
1 .下载mysql-8.0.13-x64 官方网站:https://dev.mysql.com/downloads/mysql/ 2.解压到G盘 3.准备my.ini文件保存到解压目录 [mysql ...
- iOS 控制台po不出值
本人这几天开发项目时在控制台用po命令打印时,发现总是打印不出来,这里将我的解决方案推荐给大家 方法一:(本人就是用该方法解决了问题的) 在控制台选择All Output 方法二: 按图中指示选择de ...
- Opencv-Python No module named 'cv2.cv2'
关于 No module named 'cv2.cv2'等其他一些问题,一般都是版本不兼容的问题,重装即可. pip uninstall opencv-python 然后 pip install op ...
- jenkins centos slave起不来报错The SSH key presented by the remote host does not match the key saved in the Known Hosts file against this host. Connections to this host will be denied until the two keys mat
场景:我的centos-204是一台centos的机器,本来用https://www.cnblogs.com/zndxall/p/8297356.html 的centos slave方式搭建ok的,一 ...
- python-迭代器与可迭代对象
迭代器与可迭代对象 简述 迭代是数据处理的基石.扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项.这就是迭代器模式 迭代器 迭代器是这样一个对象,实现了无参数_ ...
- CSAPP:第一章学习笔记:斗之气1段
一.信息就是位+上下文:系统中的所有信息(包括磁盘文件.内存中的程序.网络上传送的数据),都是由一串比特表示,根据上下文对这些比特表示进行翻译. 二.C程序编译过程 1.源码结构 // test.c ...
- Oracle 12.2报错ORA-15032、ORA-15410或ORA-15411解决
现象:在Oracle 12.2.0.1 RAC环境,在其ASM实例中,如果添加不同大小或者不同数量的LUN到failgroup中,会报错: ORA-15032: not all alterations ...
- SQL Server创建存储过程——动态SQL
简介: 存储过程(stored procedure)是一组为了完成特定功能的SQL语句集合,经编译后存储在服务器端的数据库中,利用存储过程可以加速SQL语句的执行. 自定义存储过程,由用户创建并能完成 ...
- 北京大学Cousera学习笔记--4-计算导论与C语言基础--计算机的基本原理-程序运行的基本原理
已知:电路能完成计算 怎么计算:设计好很多个原子电路,需要的时候就把他们临时组装在一起--ENIAC 升级:冯诺依曼-EDVAC(现在的计算机都是) 1.通过某种命令来控制计算机.让计算机按照这种命令 ...