中山市选 #E 参数拟合

中山市选 #E 参数拟合

题目大意

有两个长度为 n 的序列 A,B。现在给出你 m 种操作,(u,v) 表示你可以将 Au,Av 同时增加 q 为任意整数

最后需要使得 (AiBi)2 最小。

解题思路

首先,我们令 Ci=AiBi 这样我们的目标就是使得 Ci2 尽量小。

不难想到建一张图。

对于每一个连通块必然是单独考虑。

在一个连通块内,我们不妨以任意一个点为根,先跑出一棵树,规定父亲的深度为 1

对于树边,我们可以把儿子的 Ci 全部减到其父亲上。

这样我们可以计算出父亲节点最后剩余的 C0

  • i 节点深度为奇数,则对 C0 贡献 Ci
  • i 节点深度为偶数,则对 C0 贡献 Ci

接下来考虑非树边。

如果有非树边连接深度奇偶性不同的点 u,v,我们不妨设根节点将 C0 分给 u 方向(u 深度为奇数) av 方向 b

那么 Cu=a,Cv=b

作差,发现 Cu=ab,由于 a+b=d,且都为整数,故可以使得 Cu=dmod2

如果有非树边连接深度奇偶性相同的点,定义同上。

那么 Cu=a,Cv=b

作差,发现 Cu=a+b=d 仍然无法解决问题。

Di=|Ci|,代价为 Di2 我们可以在保证 Di=|C0| 的情况下尽量均摊(整数),来使得代价最小,可以用柯西不等式简单证明。

计算过程详见代码中 Calc 函数。

参考代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6;
struct Edge{int u,v,nxt;};
int n,m;
int a[maxn+5];
int hd[maxn+5],et;
Edge e[maxn+5];
int de[maxn+5];
int tsum,tcnt;
bool flg;
int ans;
inline void Adde(int u,int v){
e[et].u=u,e[et].v=v,e[et].nxt=hd[u],hd[u]=et++;
}
void Dfs(int u){
int v;
tcnt++;
if(de[u]&1) tsum+=a[u];
else tsum-=a[u];
for(int i=hd[u];~i;i=e[i].nxt){
v=e[i].v;
if(de[v]){
if((de[v]&1)==(de[u]&1)) flg=1;
}
else{
de[v]=de[u]+1;
Dfs(v);
}
}
}
inline int Calc(int sum,int cnt){
int res,tmp;
tmp=sum%cnt;
res=sum/cnt;
return tmp*(res+1)*(res+1)+(cnt-tmp)*res*res;
}
signed main(){
int u,v,x;
memset(hd,-1,sizeof(hd));
memset(e,-1,sizeof(e));
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) scanf("%lld",&x),a[i]-=x;
while(m--) scanf("%lld%lld",&u,&v),Adde(u,v),Adde(v,u);
for(int i=1;i<=n;i++){
if(de[i]) continue;
tsum=tcnt=0;
flg=0;
de[i]=1;
Dfs(i);
tsum=abs(tsum);
if(flg) ans+=tsum&1;
else ans+=Calc(tsum,tcnt);
}
printf("%lld",ans);
return 0;
}
posted @   DeepSeaSpray  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示