当前位置:网站首页>P4775 [NOI2018] Intelligence Center (Line Segment Tree Merging)
P4775 [NOI2018] Intelligence Center (Line Segment Tree Merging)
2022-07-29 18:32:00 【wind__whisper】
前言
似乎也没有那么难?
But it also don't want to.
解析
For the two cross path ( u 1 , v 1 , c 1 ) , ( u 2 , v 2 , c 2 ) (u_1,v_1,c_1),(u_2,v_2,c_2) (u1,v1,c1),(u2,v2,c2),设 t = l c a ( u 1 , u 1 ) t=lca(u_1,u_1) t=lca(u1,u1) 为四个 lca 中最深的,So the cost of二倍可以写为 d i s ( u 1 , v 1 ) + d i s ( u 2 , v 2 ) + d i s ( u 1 , u 2 ) + d i s ( v 1 , v 2 ) − 2 c 1 − 2 c 2 dis(u_1,v_1)+dis(u_2,v_2)+dis(u_1,u_2)+dis(v_1,v_2)-2c_1-2c_2 dis(u1,v1)+dis(u2,v2)+dis(u1,u2)+dis(v1,v2)−2c1−2c2.
枚举 t t t 的位置,Distance can be written as d i s ( u 1 , v 1 ) + d e p u 1 − 2 c 1 + d i s ( u 2 , v 2 ) + d e p u 2 − 2 c 2 + d i s ( v 1 , v 2 ) − 2 d e p t dis(u_1,v_1)+dep_{u_1}-2c_1+dis(u_2,v_2)+dep_{u_2}-2c_2+dis(v_1,v_2)-2dep_t dis(u1,v1)+depu1−2c1+dis(u2,v2)+depu2−2c2+dis(v1,v2)−2dept,可以看成 d i s ( v 1 , v 2 ) + w 1 + w 2 − 2 d e p t dis(v_1,v_2)+w_1+w_2-2dep_t dis(v1,v2)+w1+w2−2dept 的形式.
See maximum distance,Easy to think of line segment tree maintenance of the diameter of the classical approach.
Can be seen as new“ v 1 v_1 v1” Is the original point out a length of w 1 w_1 w1 的边,So still can be depicted as a tree structure,Although there is a negative right side,But due to the negative right side there must be an endpoint is leaves,So the original conclusion or right.
Each node maintains subtree within“v”节点集合,Merge to update the answer,Line segment tree merge again can,时空复杂度 O ( m log m + n log n ) O(m\log m+n\log n) O(mlogm+nlogn).
Remember to arrive again lca The point before delete.
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("line: %d\n",__LINE__)
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {
x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
bool mem1;
const int N=2e5+100;
const ll inf=2e18;
const int mod=998244353;
const bool Flag=0;
#define add(x,y) ((((x)+=(y))>=mod)&&((x)-=mod))
inline ll ksm(ll x,ll k){
ll res(1);
while(k){
if(k&1) res=res*x%mod;
x=x*x%mod;
k>>=1;
}
return res;
}
int n,m;
struct edge{
int to,nxt,w;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y,int w){
p[++cnt]=(edge){
y,fi[x],w};fi[x]=cnt;
}
int q[N],dep[N],tim,pos[N];
ll dis[N];
int pl[N][20];
inline int jump(int x,int anc){
if(Flag) printf("jump: x=%d anc=%d\n",x,anc);
for(int k=16;k>=0;k--){
if(dep[pl[x][k]]<=dep[anc]) continue;
x=pl[x][k];
}
if(Flag) printf(" p=%d\n",x);
return x;
}
void dfs(int x,int f){
dep[x]=dep[f]+1;
pos[x]=++tim;
q[tim]=x;
pl[x][0]=f;
for(int k=1;pl[x][k-1];k++) pl[x][k]=pl[pl[x][k-1]][k-1];
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(to==f) continue;
dis[to]=dis[x]+p[i].w;
dfs(to,x);
q[++tim]=x;
}
return;
}
int mn[N][20],lg[N],mi[20];
inline int cmp(int x,int y){
return dep[x]<dep[y]?x:y;}
void ST(){
lg[0]=-1;
for(int i=1;i<=tim;i++) lg[i]=lg[i>>1]+1;
mi[0]=1;
for(int i=1;i<=lg[tim];i++) mi[i]=mi[i-1]<<1;
for(int i=1;i<=tim;i++) mn[i][0]=q[i];
for(int k=1;k<=lg[tim];k++){
for(int i=1;i+mi[k]-1<=tim;i++) mn[i][k]=cmp(mn[i][k-1],mn[i+mi[k-1]][k-1]);
}
return;
}
inline int Lca(int x,int y){
int l=pos[x],r=pos[y];
if(l>r) swap(l,r);
int k=lg[r-l+1];
//printf(" x=%d y=%d (%d %d) Lca=%d\n",x,y,pos[x],pos[y],cmp(mn[l][k],mn[r-mi[k]+1][k]));
return cmp(mn[l][k],mn[r-mi[k]+1][k]);
}
inline ll Dis(int x,int y){
return dis[x]+dis[y]-2*dis[Lca(x,y)];
}
struct pt{
int id;
ll w;
};
inline ll calc(const pt &a,const pt &b){
return Dis(a.id,b.id)+a.w+b.w;
}
int id[N],ed[N],rku[N],rkv[N];
struct node{
pt x,y;
};
inline void print(const node &a,int op=1){
printf("[ (%d %lld) (%d %lld) ] %c",a.x.id,a.x.w,a.y.id,a.y.w,op?'\n':' ');
}
inline ll getans(const node &a,const node &b){
ll q=calc(a.x,b.x),w=calc(a.x,b.y),e=calc(a.y,b.x),r=calc(a.y,b.y),mx=max({
q,w,e,r});
return mx;
}
inline node merge(const node &a,const node &b){
ll q=calc(a.x,b.x),w=calc(a.x,b.y),e=calc(a.y,b.x),r=calc(a.y,b.y),t=calc(a.x,a.y),y=calc(b.x,b.y),mx=max({
q,w,e,r,t,y});
if(mx==q) return (node){
a.x,b.x};
if(mx==w) return (node){
a.x,b.y};
if(mx==e) return (node){
a.y,b.x};
if(mx==r) return (node){
a.y,b.y};
if(mx==t) return (node){
a.x,a.y};
if(mx==y) return (node){
b.x,b.y};
assert(0);
}
struct tree{
int ls,rs;
node o;
}tr[N*30];
int rt[N],tot;
inline void pushup(int k){
tr[k].o=merge(tr[tr[k].ls].o,tr[tr[k].rs].o);
/*printf("merge: "); print(tr[tr[k].ls].o,0); print(tr[tr[k].rs].o,0); print(tr[k].o,1);*/
return;
}
#define mid ((l+r)>>1)
inline int New(){
tr[++tot]=tr[0];
return tot;
}
void upd(int &k,int l,int r,int p,ll w,int op){
if(!k) k=New();
if(l==r){
assert(id[l]);
if(op==1) tr[k].o.x=(pt){
id[l],w};
else tr[k].o.x=(pt){
id[l],-inf};
return;
}
if(p<=mid) upd(tr[k].ls,l,mid,p,w,op);
else upd(tr[k].rs,mid+1,r,p,w,op);
pushup(k);
return;
}
int merge(int x,int y){
if(!x||!y) return x|y;
int now=++tot;
tr[now].ls=merge(tr[x].ls,tr[y].ls);
tr[now].rs=merge(tr[x].rs,tr[y].rs);
pushup(now);
return now;
}
struct ope{
int op,p;
ll w;
};
vector<ope>ve[N];
int u[N],v[N];
ll c[N];
int S;
ll ans;
void solve(int x,int f){
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(to==f) continue;
solve(to,x);
}
if(Flag) printf("solve: x=%d\n",x);
for(ope o:ve[x]){
if(o.op==1){
pt ww=(pt){
id[o.p],o.w};
ans=max(ans,calc(ww,tr[rt[x]].o.x)-2*dis[x]);
ans=max(ans,calc(ww,tr[rt[x]].o.y)-2*dis[x]);
upd(rt[x],1,S,o.p,o.w,o.op);
if(Flag) printf(" ins: p=%d x=%d\n",o.p,id[o.p]);
}
}
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(to==f) continue;
ll o=getans(tr[rt[x]].o,tr[rt[to]].o)-2*dis[x];
if(Flag) if(o>ans){
printf("%d -> %d o=%lld ",x,to,o);
print(tr[rt[x]].o,0);
print(tr[rt[to]].o,1);
}
ans=max(ans,o);
rt[x]=merge(rt[x],rt[to]);
}
for(ope o:ve[x]){
if(o.op==-1){
upd(rt[x],1,S,o.p,o.w,o.op);
if(Flag) printf(" del: p=%d x=%d\n",o.p,id[o.p]);
}
}
return;
}
void init(){
tim=0;
cnt=-1;
tot=0;
ans=-inf;
tr[0].o.x=tr[0].o.y=(pt){
1,-inf};
for(int i=1;i<=n;i++){
fi[i]=-1;
memset(pl[i],0,sizeof(pl[i]));
ed[i]=0;
rt[i]=0;
ve[i].clear();
}
}
void work(){
n=read();
init();
for(int i=1;i<n;i++){
int x=read(),y=read(),w=read();
addline(x,y,w);
addline(y,x,w);
}
dfs(1,0);
ST();
m=read();
for(int i=1;i<=m;i++){
u[i]=read();v[i]=read();
c[i]=Dis(u[i],v[i])-read()*2;
rku[i]=++ed[u[i]];rkv[i]=++ed[v[i]];
}
for(int i=1;i<=n;i++){
ed[i]+=ed[i-1];
for(int j=ed[i-1]+1;j<=ed[i];j++) id[j]=i;
}
S=ed[n];
for(int i=1;i<=m;i++){
int anc=Lca(u[i],v[i]);
if(anc!=u[i]){
int p=jump(u[i],anc);
ve[u[i]].push_back((ope){
1,ed[v[i]-1]+rkv[i],c[i]+dis[u[i]]});
ve[p].push_back((ope){
-1,ed[v[i]-1]+rkv[i],c[i]+dis[u[i]]});
}
if(anc!=v[i]){
int p=jump(v[i],anc);
ve[v[i]].push_back((ope){
1,ed[u[i]-1]+rku[i],c[i]+dis[v[i]]});
ve[p].push_back((ope){
-1,ed[u[i]-1]+rku[i],c[i]+dis[v[i]]});
}
}
solve(1,0);
if(ans<-1e18) puts("F");
else printf("%lld\n",ans>>1);
}
bool mem2;
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
debug("mem=%.2lf\n",abs(&mem2-&mem1)/1024./1024);
int T=read();
while(T--){
//if(T%100==0) debug("%d\n",T);
work();
}
return 0;
}
边栏推荐
- 2022 年 WebAssembly 应用现状
- factorial factorization
- 不同的 DAO 对世界带来的改变
- Fast Reed-Solomon Interactive Oracle Proofs of Proximity学习笔记
- 清道夫受体-A靶向脂肪酸修饰白蛋白纳米粒/银耳多糖修饰白蛋白微球的制备
- 利用 JMeter 压测上传和下载接口实战
- How CRM Helps Enterprise Marketing Acquire Customers
- Babbitt | Metaverse Daily Must Read: Seven consecutive quarters of losses, Meta Metaverse division Q2 loss of $ 2.8 billion, Zuckerberg said this situation may continue for years ...
- 【南瓜书ML】(task5)支持向量机的数学推导(更新ing)
- lua-调试技巧
猜你喜欢
使用LIMIT分页
leetcode53 -- 最大数组和
UNIX Environment Advanced Programming Chapter 3
「记录」MMDetection入门篇
解析正则表达式(一)
Babbitt | Metaverse Daily Must Read: Seven consecutive quarters of losses, Meta Metaverse division Q2 loss of $ 2.8 billion, Zuckerberg said this situation may continue for years ...
【英语考研词汇训练营】Day 17 —— espresso,ultimate,gradually,detect,dimension
巴比特 | 元宇宙每日必读:连续七个季度出现亏损,Meta元宇宙部门Q2亏损28 亿美元,扎克伯格称这种情况可能会持续数年...
js骏马奔腾点击裁剪js特效
"Record" MMDetection Introduction
随机推荐
The structure of the earth's over 200 million proteins is fully predicted, and AlphaFold detonates the "protein universe"
【深度学习】YOLO转VOC VOC转YOLO
刚刚,60后复旦校友IPO敲钟:市值400亿
直播实录 | 37 手游如何用 StarRocks 实现用户画像分析
提高编程效力的5大VS Code Extensions
canvas随机生成树木js特效
大佬们一个 sql 优化问题。我有个4千万的表。然后加了一个字段,只有10+条数据会给值,其他行数据
Greedy (1) interval complete coverage problem
「硬核」labelme 图片中显示标签
解析idea中的debug调试模式
使用LIMIT分页
leetcode136 -- 只出现一次的数字
SSM整合案例分析(详解)
泰山OFFICE技术讲座:影响文字效果的因素,由四大升级为五大
HER2-2-ME-BSANPs单抗特异性的2-甲氧基雌二醇白蛋白纳米粒的研究与制备
js图片等分对比插件
xatlas源码解析(七)
Arduino框架下轻量级ssd1306 I2C屏幕驱动库
large number factorial calculation
一文搞定代码中的命名