CF1916G Optimizations From Chelsu 题解
Optimizations From Chelsu
题意
给定
大致思路
我们考虑共用一个顶点的两条链对答案的更新情况,令他们长度,gcd,分别为
1.
2.
推导: 设
于是我们可以考虑淀粉质,枚举重心之后,对于每个
复杂度证明
考虑每一层分治,对于每个
code
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100005
int zu,n,k,mxl,cnt,t1,t2,t3;
int h[N],ct[N],sz[N],mxs[N],q1[N],q2[N],q3[N];
ll ans,maxn,q[N];
map<ll,int> mp,id,mp2;
struct AB{
int a,b;
ll c;
int n;
}d[N*2];
void cun(int x,int y,ll z){
d[++k]={x,y,z,h[x]},h[x]=k;
}
ll gcd(ll x,ll y){
if(x%y==0) return y;
return gcd(y,x%y);
}
void dfs(int x,int fa,ll g,int len,int num){
maxn=max(maxn,g),mxl=max(mxl,len);
if(mp.find(g)==mp.end()) mp[g]=len,id[g]=num;
else{
if(len>=mp[g]){
if(num==id[g]) mp[g]=len;
else mp2[g]=mp[g],id[g]=num,mp[g]=len;
}
else if(len>=mp2[g]){
if(num!=id[g]) mp2[g]=len;
}
}
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(y==fa||ct[y]) continue;
dfs(y,x,gcd(g,d[i].c),len+1,num);
}
}
void gt_sz(int x,int fa){
sz[x]=1,mxs[x]=0;
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(y==fa||ct[y]) continue;
gt_sz(y,x);sz[x]+=sz[y],mxs[x]=max(sz[y],mxs[x]);
}
}
int gt_rt(int x,int fa,int siz){
int q=x,p;
mxs[x]=max(mxs[x],siz-sz[x]);
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(y==fa||ct[y]) continue;
p=gt_rt(y,x,siz);
if(mxs[p]<mxs[q]) q=p;
}
return q;
}
void solve(int x){
gt_sz(x,0);
x=gt_rt(x,0,sz[x]);
mp.clear(),id.clear(),mp2.clear(),maxn=mxl=0;
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(ct[y]) continue;
dfs(y,x,d[i].c,1,y);
}
t1=t2=t3=0;
for(auto p:mp) q[++t1]=p.first,q1[t1]=p.second,q3[t1]=0;
for(auto p:id) q2[++t2]=p.second;
for(auto p:mp2){
while(q[t3]<p.first) t3++;
q3[t3]=p.second;
}
for(int i=1;i<=t1;i++){
ll g=q[i];
int len=q1[i];
if(1ll*g*(len+mxl)<=ans) continue;
int num=q2[i];
for(int k=1;k<=len&&1ll*g*k<=maxn;k++){
ll g2=1ll*g*k;
int j=lower_bound(q+1,q+1+t1,g2)-q;
if(q[j]!=g2) continue;
if(q2[j]==num) ans=max(ans,1ll*(q3[j]+len)*g);
else ans=max(ans,1ll*(q1[j]+len)*g);
}
}
ct[x]=1;
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(ct[y]) continue;
solve(y);
}
}
inline int read(){
int num=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while('0'<=c&&c<='9') num=(num<<3)+(num<<1)+c-'0',c=getchar();
return num;
}
signed main(){
scanf("%d",&zu);
while(zu--){
scanf("%d",&n);
k=0;
for(int i=1;i<=n;i++) h[i]=ct[i]=0;
for(int i=1,x,y;i<n;i++){
ll z;
x=read(),y=read(),scanf("%lld",&z);
cun(x,y,z),cun(y,x,z);
}
ans=0,solve(1);
printf("%lld\n",ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】