BZOJ3528: [Zjoi2014]星系调查
唉,看到这题直接想起自己的Day1,还是挺难受的,挺傻一题考试的时候怎么就没弄出来呢……
这两天CP让我给他写个题解,弄了不是很久就把这个题给弄出来了,真不知道考试的时候在干嘛。
明天就出发去北京了,祝自己APIO顺利吧。

/**************************************************************
Problem: 3528
User: zhuohan123
Language: C++
Result: Accepted
Time:1736 ms
Memory:25408 kb
****************************************************************/ #include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const double eps=1e-;
inline int getnum()
{
int ans=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh*=-;ch=getchar();}
while(ch>=''&&ch<='')ans=ans*+ch-'',ch=getchar();
return fh*ans;
}
struct info
{
int n,x,y,x2,y2,xy;
info(){n=x=y=x2=y2=xy=;}
info(int X,int Y){n=;x=X;y=Y;x2=X*X;y2=Y*Y;xy=X*Y;}
info(int N,int X,int Y,int X2,int Y2,int XY){n=N;x=X;y=Y;x2=X2;y2=Y2;xy=XY;}
inline friend info operator+(info a,info b){return info(a.n+b.n,a.x+b.x,a.y+b.y,a.x2+b.x2,a.y2+b.y2,a.xy+b.xy);}
inline friend info operator-(info a,info b){return info(a.n-b.n,a.x-b.x,a.y-b.y,a.x2-b.x2,a.y2-b.y2,a.xy-b.xy);}
inline info operator+=(info b){n+=b.n;x+=b.x;y+=b.y;x2+=b.x2;y2+=b.y2;xy+=b.xy;return *this;}
inline double xbar(){return (double)x/(double)n;}
inline double ybar(){return (double)y/(double)n;}
inline double A(){return x2-*xbar()*x+n*xbar()*xbar();}
inline double B(){return *ybar()*x+*xbar()*y-*xy-*n*xbar()*ybar();}
inline double C(){return y2-*ybar()*y+n*ybar()*ybar();}
inline double delta()
{
if(n==)return ;
double a=A(),b=B(),c=C(),d=sqrt(a*a+b*b+c*c-*a*c);
double ans1=(a+c+d)/,ans2=(a+c-d)/;
if(ans1>ans2)swap(ans1,ans2);
return ans1>-eps?ans1:ans2;
}
};
int n,m;
struct point
{
int head,f[],deep,incir,wt;
info x;
}p[];
struct edge{int next,to;}g[];int gnum;
void addedge(int from,int to)
{
g[++gnum].to=to;g[gnum].next=p[from].head;p[from].head=gnum;
g[++gnum].to=from;g[gnum].next=p[to].head;p[to].head=gnum;
}
namespace Tree
{
void dfs(int po)
{
p[po].deep=p[p[po].f[]].deep+;
for(int i=;i<=;i++)
p[po].f[i]=p[p[po].f[i-]].f[i-];
for(int i=p[po].head;i;i=g[i].next)
if(g[i].to!=p[po].f[])
{
p[g[i].to].x+=p[po].x;
p[g[i].to].f[]=po;
dfs(g[i].to);
}
}
inline int lca(int u,int v)
{
if(p[u].deep>p[v].deep)swap(u,v);
for(int i=;i>=;i--)
if(p[p[v].f[i]].deep>=p[u].deep)v=p[v].f[i];
if(u==v)return u;
for(int i=;i>=;i--)
if(p[v].f[i]!=p[u].f[i])v=p[v].f[i],u=p[u].f[i];
return p[v].f[];
}
void solve()
{
dfs();
int q=getnum();
while(q--)
{
int u=getnum(),v=getnum(),l=lca(u,v);
printf("%.5lf\n",(p[u].x+p[v].x-p[l].x-p[p[l].f[]].x).delta()+eps);
}
}
}
namespace Circle
{
bool ins[];
int s[],sr;
int cir[],cnum;
info cinfo[];
inline info cirwalk(int l,int r){return cinfo[r]-cinfo[l-];}
bool dfscir(int po,int from)
{
ins[s[++sr]=po]=true;
for(int i=p[po].head;i;i=g[i].next)
if(g[i].to!=from)
{
if(ins[g[i].to])
{
while(s[sr]!=g[i].to)
{
cir[++cnum]=s[sr];
p[s[sr]].incir=cnum;
sr--;
}
cir[++cnum]=g[i].to;
p[g[i].to].incir=cnum;
return true;
}
else if(dfscir(g[i].to,po))return true;
}
sr--;
ins[po]=false;return false;
}
void dfstree(int po,int wt)
{
p[po].wt=wt;
p[po].deep=p[p[po].f[]].deep+;
for(int i=;i<=;i++)
p[po].f[i]=p[p[po].f[i-]].f[i-];
for(int i=p[po].head;i;i=g[i].next)
if(g[i].to!=p[po].f[]&&!p[g[i].to].incir)
{
p[g[i].to].x+=p[po].x;
p[g[i].to].f[]=po;
dfstree(g[i].to,wt);
}
}
inline int lca(int u,int v)
{
if(p[u].deep>p[v].deep)swap(u,v);
for(int i=;i>=;i--)
if(p[p[v].f[i]].deep>=p[u].deep)v=p[v].f[i];
if(u==v)return u;
for(int i=;i>=;i--)
if(p[v].f[i]!=p[u].f[i])v=p[v].f[i],u=p[u].f[i];
return p[v].f[];
}
void solve()
{
dfscir(,);
for(int i=;i<=cnum;i++)dfstree(cir[i],cir[i]);
for(int i=;i<=cnum;i++)cir[i+cnum]=cir[i];
for(int i=;i<=*cnum;i++)cinfo[i]=cinfo[i-]+p[cir[i]].x;
int q=getnum();
while(q--)
{
int u=getnum(),v=getnum();
if(p[u].wt==p[v].wt)
{
int l=lca(u,v);
printf("%.5lf\n",(p[u].x+p[v].x-p[l].x-p[p[l].f[]].x).delta()+eps);
}
else
{
int fu=p[u].wt,fv=p[v].wt;
info iu=p[u].x-p[fu].x,iv=p[v].x-p[fv].x;
if(p[fu].incir>p[fv].incir)swap(fu,fv);
info imid1=cirwalk(p[fu].incir,p[fv].incir);
info imid2=cirwalk(p[fv].incir,p[fu].incir+cnum);
printf("%.5lf\n",min((iu+imid1+iv).delta(),(iu+imid2+iv).delta())+eps);
}
}
}
}
int main(int argc, char *argv[])
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
n=getnum(),m=getnum();
for(int i=;i<=n;i++)
{
int x=getnum(),y=getnum();
p[i].x=info(x,y);
}
for(int i=;i<=m;i++)addedge(getnum(),getnum());
if(m==n-)Tree::solve();
else Circle::solve();
return ;
}
BZOJ3528: [Zjoi2014]星系调查的更多相关文章
- bzoj 3528 [ZJOI2014] 星系调查 题解
[原题] 星系调查 [问题描写叙述] 银河历59451年.在银河系有许很多多已被人类殖民的星系.如果想要在行 星系间往来,大家一般使用连接两个行星系的跳跃星门. 一个跳跃星门能够把 物质在它所连接的 ...
- bzoj 3528: [Zjoi2014]星系调查
Description 银河历59451年,在银河系有许许多多已被人类殖民的星系.如果想要在行 星系间往来,大家一般使用连接两个行星系的跳跃星门. 一个跳跃星门可以把 物质在它所连接的两个行星系中互 ...
- bzoj 3528 [Zjoi2014]星系调查【树链剖分+数学】
参考:https://www.cnblogs.com/zhuohan123/p/3698852.html 首先,根据点到直线距离公式 \[ d=\frac{kx_0-y_0+b}{\sqrt{k^{2 ...
- 题解 洛谷 P3340 【[ZJOI2014]星系调查】
根据题意,发现题目中的图,其实就是一颗树或者是一颗基环树,每个节点上有一个点对\((x,y)\),每次询问为给定端点,找一条直线到端点间的所有点的距离之和最小. 设这条直线为\(y=kx+b\),根据 ...
- 「ZJOI2014」星系调查
「ZJOI2014」星系调查 本题核心在于快速求XPs 的线性假设相斥度. 点\((x1,y1)\)到直线\(y=kx+b\)的距离的平方为\(\displaystyle {(kx1+b-y1)^2} ...
- ZJOI 2014 星系调查(推导)
题意 https://loj.ac/problem/2201 思路 说白了就是一条路径上有 \(n\) 个二维坐标,求一条直线使得所有点到此直线的距离和最小. 设这条直线为 \(y=kx+b\) ,距 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- O365(世纪互联)SharePoint 之调查列表简单介绍
前言 SharePoint中为了提供了很多开箱即用的应用程序,比如调查列表就是其中之一,同样,在O365版本里(国际版和世纪互联版本均可),也有这样的调查列表可以供我们使用,而使用起来非常方便和快速, ...
- Office 365使用情况调查不完全分析报告
感谢大家参与了9月13日在Office 365技术群(O萌)中发起的一个关于Office 365使用情况的调查,在一天左右的时间内,我们一共收到了67份反馈,其中绝大部分是在3分钟内提交的. 本次调查 ...
随机推荐
- python线程池/进程池创建
进程池 import time from concurrent.futures import ProcessPoolExecutor def task(arg): time.sleep(2) prin ...
- 【我的Android进阶之旅】解决Android Studio启动时报错:Java 1.8 or later is required.
错误描述 在公司电脑上运行Android Studio 2.2已经有一段时间了,但是自己的笔记本上还是用的Android Studio 1.5,今天晚上下了一个Android Studio 2.2压缩 ...
- 0406-服务注册与发现-客户端feign-使用、配置、日志、timeout
官方地址:https://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#spring-cloud-f ...
- MDK中One ELF Section per Function选项功能探究【转载】
本文主要探讨的是MDK开发工具中One ELF Section per Function选项对于代码优化的作用及其实现的机制. 这里以EK-STM32F开发板的LCDDemo实验例程为例进行说明: 1 ...
- Jupyter Notebook修改目标文件
默认的路径 如果没有修改配置文件,那么一般就在用户目录下面: 下面各处默认起始目标地址,以防有一天想改回来 I:\shujufenxi\python.exe I:\shujufenxi\cwp.py ...
- 浅谈WebService SOAP、Restful、HTTP(post/get)请求
http://www.itnose.net/detail/6189456.html 浅谈WebService SOAP.Restful.HTTP(post/get)请求 2015-01-09 19:2 ...
- js小技巧(收集的)
一.事件源对象 event.srcElement.tagName //IE浏览器 event.srcElement.type event.target.tagName //dom浏览器 event.t ...
- spring的线程安全
Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”.但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码.Spring对每个bean提供 ...
- JavaScript返回顶部特效
样式: <style type="text/css"> /*返回顶部特效*/ a { border: none; text-decoration: none; outl ...
- Spark机器学习1·编程入门(scala/java/python)
Spark安装目录 /Users/erichan/Garden/spark-1.4.0-bin-hadoop2.6 基本测试 ./bin/run-example org.apache.spark.ex ...