首页 > 其他分享 >[ZJOI2014]星系调查

[ZJOI2014]星系调查

时间:2022-10-06 16:56:23浏览次数:38  
标签:pre frac int sum 调查 overline ZJOI2014 星系 dis

做题时间:2022.10.5

\(【题目描述】\)

给定一个点数为 \(n(n\leq 4\times 10^5)\),边数为 \(m(4\times 10^5)\) 的无向联通图,满足 \(m\leq n\),对于第 \(i\) 个点,给定一个笛卡尔坐标系上的点 \((X_i,Y_i)\),先有 \(Q(Q\leq 4\times 10^5)\) 次询问,每次询问给出图上两个不同的点 \(s_i,t_i\) ,对于每一条图上 \(s_i\) 到 \(t_i\) 的简单路径的所有点,求其线性假设相斥度最小值。(线性假设相斥度:对于一个点集,对于一条直线 \(l\),这条直线与点集中所有点的欧几里得距离之和的最小可能值)

\(【输入格式】\)

第一行两个整数 \(n,m\),表示点数和边数

接下来 \(n\) 行,每行两个整数表示 \(X_i,Y_i\)

接下来 \(m\) 行,每行两个整数 \(u,v\) 表示图中的一条边 \((u,v)\)

接下来一行一个整数 \(q\) 表示询问次数

接下来 \(q\) 行每行两个整数 \(s_i,t_i\) 表示询问

\(【输出格式】\)

输出共 \(q\) 行,对于每一个询问输出一行一个浮点数表示答案。要求绝对值误差不超过 \(10^{-4}\)

\(【考点】\)

数学、二次函数、基环树、差分

\(【做法】\)

初中奥数题

首先这种猎奇的询问没有什么较好的方法直接求,可以考虑化一下柿子。

可以知道点 \((x_i,y_i)\) 到直线 \(Ax+By=C\) 的距离公式为:

\[dis=\frac{|Ax_i+By_i+C|}{\sqrt{A^2+B^2}} \]

但是带入计算的时候肯定要消元,三个未知数不太好搞,可以用斜率柿子:

\[dis=\frac{|kx_i-y_i+b|}{\sqrt{k^2+1}} \]

所以,要求的便是:

\[\begin{aligned} ans &=\sum\limits_{i=s_i}^{t_i}dis((x_i,y_i),l)^2 \\ &=\sum\limits_{i=s_i}^{t_i} \frac{(kx_i-y_i+b)^2}{k^2+1} \\ &= \frac{1}{k^2+1}(k^2\sum x_i^2-2k\sum x_iy_i +\sum y_i^2+2kb\sum x_i-2b\sum y_i +dis\times b^2) \end{aligned} \]

的最小值。然后发现原式中包含了 \(k\) 和 \(b\) 两个未知数,先消掉一个。即,设 \(k\) 为常数,将与 \(b\) 有关的柿子:

\[dis\times b^2+2(k\sum x_i-\sum y_i)b \]

变为最小值。这个柿子是个关于 \(b\) 的开口向上的二次函数,因此它取最小值时:

\[b=\frac{\sum y_i-k\sum x_i}{dis} \]

令 \(\overline{y_i}=\frac{\sum y_i}{dis}\),\(\overline{x_i}=\frac{\sum x_i}{dis}\),将 \(b\) 带回原式,并将含 \(k\) 项整理,有:

\[\frac{k^2\sum(x_i^2-2x_i\overline{x}+\overline{x}^2)+k\sum (2x_i\overline{y}-2x_iy_i+2\overline{x}y_i-2\overline{x}\overline{y})+\sum(y_i^2-2y_i\overline{y}+\overline{y}^2)}{k^2+1} \]

换元一下,令:

\[\begin{aligned} A&=\sum(x_i^2-2x_i\overline{x}+\overline{x}^2)\\ B&=\sum (2x_i\overline{y}-2x_iy_i+2\overline{x}y_i-2\overline{x}\overline{y})\\ C&=\sum(y_i^2-2y_i\overline{y}+\overline{y}^2) \end{aligned} \]

原式可化为:

\[\frac{Ak^2+Bk+C}{k^2+1} \]

(其中 \(A,B,C\) 为常数) 是不是很眼熟

像这种分数线上下均为关于相同未知数的二次函数,可以分离常数,也可以直接化成二次函数的形式用 \(\Delta\) 讨论,具体而言,令

\[t=\frac{Ak^2+Bk+C}{k^2+1} \]

有:

\[tk^2+t=Ak^2+Bk+C \]

\[(A-t)k^2+Bk+(C-t)=0 \]

原式有解,有:

\[\begin{aligned} \Delta &=B^2-4(A-t)(C-t)\\ &=-4t^2+4(A+C)t+B^2-4AC\geq 0 \end{aligned} \]

这个关于 \(t\) 的二次函数开口向下,又大于等于0,因此 \(t\) 的取值必须在与 \(x\) 轴的交点之间,即 \(t\in[\frac{-b-\sqrt{\Delta}}{2a},\frac{-b+\sqrt{\Delta}}{2a}]\) ,所以:

\[t_{min}=\frac{A+C-\sqrt{A^2+B^2+C^2-2AC}}{2} \]

然后就可以 \(O(1)\) 求解力(喜

回到原题,\(m\leq n\) 意味着图为基环树或树,直接预处理 \(\sum x_i\) 等一堆东西即可。对于基环树而言将环找出来, 以环为主体 ,若询问两点在以环上某点为根的同一棵子树上,直接求解,否则将环上两种路径对应的解取个最小值就行了。

\(【代码】\)

#include<cstdio>
#include<iomanip>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=5e5+50;
struct edge{
	int to,nxt;
}a[N<<1];
struct point{
	#define sumx(a) a.sumx
	#define sumy(a) a.sumy
	#define mulx(a) a.mulx
	#define muly(a) a.muly
	#define sumxy(a) a.sumxy
	#define len(a) a.len

	ll sumx,sumy,mulx,muly,sumxy,len;
	void Insert(int a,int b)
	{
		sumx+=(ll)a,sumy+=(ll)b;
		sumxy+=(ll)a*b,mulx+=(ll)a*a,muly+=(ll)b*b,len++;
	}
	double calc()
	{
		double A=mulx-1.0*(sumx*sumx)/len;
		double B=-2*sumxy+2.0*sumx*sumy/len;
		double C=muly-1.0*(sumy*sumy)/len;
		return (A+C-sqrt(A*A+B*B+C*C-2*A*C))/2;
	}
	point operator +(const point a)
	{
		return (point){sumx(a)+sumx,sumy(a)+sumy,mulx(a)+mulx,
		muly(a)+muly,sumxy(a)+sumxy,len(a)+len};
	}
	point operator -(const point &a)
	{
		return (point){sumx-sumx(a),sumy-sumy(a),mulx-mulx(a),
		muly-muly(a),sumxy-sumxy(a),len-len(a)};
	}
}sum[N],pre[N];
bool Is_cir[N];
int head[N],dep[N],col[N],f[N][25],fa[N];
int cir[N],x[N],y[N],pos[N],cnt,ed,n,m;
inline int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);}
inline bool Merge(int x,int y)
{
	int X=Find(x),Y=Find(y);
	if(X==Y) return true;
	fa[X]=Y;
	return false;
}
inline void dfs(int u,int fa,int c)
{
	dep[u]=dep[fa]+1,col[u]=c,f[u][0]=fa;
	pre[u]=pre[fa];
	pre[u].Insert(x[u],y[u]);
	for(int i=1;i<25;i++) f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i;i=a[i].nxt){
		int v=a[i].to;
		if(v!=fa&&!Is_cir[v]) dfs(v,u,c);
	}
}
inline bool Find_cir(int u,int fa,int st)
{
	if(Is_cir[u]&&u!=st) return true;
	for(int i=head[u];i;i=a[i].nxt){
		int v=a[i].to;
		if(v!=fa&&!(Is_cir[u]&Is_cir[v])){
			cir[++ed]=v;
			if(!Find_cir(v,u,st)) ed--;
			else return true;
		}
	}
}
inline int lca(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=24;i>=0;i--){
		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
	}
	if(x==y) return x;
	for(int i=24;i>=0;i--){
		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
	}
	return f[x][0];
}
void add(int u,int v)
{
	cnt++;
	a[cnt].to=v;
	a[cnt].nxt=head[u];
	head[u]=cnt;
}
double solve(int x,int y)
{
	int l=lca(x,y);
	point now=pre[x]+pre[y]-pre[l]-pre[f[l][0]];
	return now.calc(); 
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y),add(x,y),add(y,x);
		if(Merge(x,y)) cir[++ed]=x,Is_cir[x]=Is_cir[y]=true;//并查集找环
	}
	if(m==n-1) dfs(1,0,0);
	else{
		Find_cir(cir[1],0,cir[1]);
		for(int i=1;i<=ed;i++){
			int now=cir[i];
			pos[now]=i,Is_cir[now]=true;
			sum[i]=sum[i-1],sum[i].Insert(x[now],y[now]); 
		}
		for(int i=1;i<=ed;i++) dfs(cir[i],0,cir[i]); 
	}
	int q;
	scanf("%d",&q);
	while(q--){
		int x,y;
		scanf("%d%d",&x,&y);
		if(m==n-1||col[x]==col[y]) printf("%lf\n",solve(x,y));//如果是一棵树或是基环树上同一子树内
		else{
			int posx=pos[col[x]],posy=pos[col[y]];
			if(posx>posy) swap(posx,posy);
			point now=pre[x]+pre[y]-pre[col[x]]-pre[col[y]];
			
			point ans1=now+sum[posy]-sum[posx-1],ans2=now+sum[ed]+sum[posx]-sum[posy-1];
			printf("%lf\n",min(ans1.calc(),ans2.calc()));
		}
	}
	return 0;
}

标签:pre,frac,int,sum,调查,overline,ZJOI2014,星系,dis
From: https://www.cnblogs.com/Unlimited-Chan/p/16757962.html

相关文章

  • 技工工资大调查!你拖后腿了吗?
    技术工人是指掌握了一定的技术能力、从事相关技术工作的熟练工人。据统计,2015年,我国一二线城市的工人平均年薪是5万多元,其中制造型企业普通一线员工平均年收入56856元,非......
  • 2022中国消费者智能网联汽车数据安全和个人隐私意识与顾虑调查报告
    报告链接:http://tecdat.cn/?p=28552 该调查于2021年11月至12月通过《环球时报》和君迪微信公众号进行样本收集,重点研究了消费者对智能网联汽车数据安全的认知、信心和担......
  • 作为 Android 工程师进行尽职调查
    作为Android工程师进行尽职调查作者:伊山·卡纳,高级软件工程师,Android我最近发表了关于作为Android工程师进行尽职调查的演讲。在参与了多个涉及与第三方供应......
  • 敏感问题调查 干扰变量 抛硬币
    说说不能说的话——敏感问题调查https://mp.weixin.qq.com/s/q_a_1Psbbdwzqkiufm4TOQ说说不能说的话——敏感问题调查原创 房祥忠 统计之都 2022-09-0308:31 发表......