月下“毛景樹”
此題不板,何板之有?
是不板,孰板?
同 T1,需要邊權下放到點權,考慮 DFS1 的時候就下放
注意 LCA 不能算進去
gigo 大佬是算了 LCA ,調了一下午,我是沒考慮 cover 和 add 操作的優先級,調了一下午
cover 比 add 要優先一些,因爲 cover 了 add 就沒用了
單獨下放邊權,思路比較清晰一些(giaohr巨巨的代碼;並且我請求大家不要訪問他的博客,因爲這樣會增加他的訪問量)
#include<bits/stdc++.h>
#define in Read()
#define int long long
using namespace std;
inline int in{
int i=0,f=1;char ch;
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')ch=getchar(),f=-1;
while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int NNN=1e5+5;
const int INF=1e9+7;
int n;
char q[50];
int tot;
int first[NNN];
int nxt[NNN<<1];
int aim[NNN<<1];
int wei[NNN];
int to1[NNN];
int to2[NNN];
int faz[NNN];
int dep[NNN];
int siz[NNN];
int son[NNN];
int top[NNN];
int dfn[NNN];
int idx[NNN];
int dwn[NNN];
int val[NNN];
int ord;
struct Tree{
int l,r;
int max;
int add;
int cov;
}tre[NNN<<2];
inline void add(int u,int v){
++tot;
nxt[tot]=first[u];
first[u]=tot;
aim[tot]=v;
return;
}
inline void DFS1(int fa,int u){
faz[u]=fa;
dep[u]=dep[fa]+1;
siz[u]=1;
for(int e=first[u];e;e=nxt[e]){
int v=aim[e];
if(v==fa) continue;
DFS1(u,v);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v]) son[u]=v;
}
return;
}
inline void DFS2(int u,int tp){
top[u]=tp;
dfn[u]=++ord;
idx[ord]=u;
if(!son[u]) return;
DFS2(son[u],tp);
for(int e=first[u];e;e=nxt[e]){
int v=aim[e];
if(v==faz[u]||v==son[u]) continue;
DFS2(v,v);
}
return;
}
inline void push_road(){
for(int i=1;i<n;++i){
dwn[i]=dep[to1[i]]<dep[to2[i]]?to2[i]:to1[i];
val[dwn[i]]=wei[i];
}
return;
}
#define lch p<<1
#define rch p<<1|1
#define tr tre[p].r
#define tl tre[p].l
inline void push_up(int p){
tre[p].max=max(tre[lch].max,tre[rch].max);
return ;
}
inline void push_down(int p){
if(tre[p].cov!=-1){
tre[lch].max=tre[p].cov;
tre[rch].max=tre[p].cov;
tre[lch].cov=tre[p].cov;
tre[rch].cov=tre[p].cov;
tre[lch].add=0;
tre[rch].add=0;
tre[p].cov=-1;
}
if(tre[p].add){
tre[lch].add+=tre[p].add;
tre[rch].add+=tre[p].add;
tre[lch].max+=tre[p].add;
tre[rch].max+=tre[p].add;
tre[p].add=0;
}
return;
}
inline void build(int p,int l,int r){
tr=r,tl=l;
tre[p].cov=-1;
tre[p].max=-INF;
if(l==r){
tre[p].max=val[idx[l]];
return;
}
int mid=l+r>>1;
build(lch,l,mid);
build(rch,mid+1,r);
push_up(p);
return;
}
inline void cover(int p,int l,int r,int w){
if(l<=tl&&tr<=r){
tre[p].max=w;
tre[p].cov=w;
tre[p].add=0;
return;
}
push_down(p);
int mid=tl+tr>>1;
if(l<=mid) cover(lch,l,r,w);
if(r>mid) cover(rch,l,r,w);
push_up(p);
return;
}
inline void update(int p,int l,int r,int w){
if(l<=tl&&tr<=r){
tre[p].max+=w;
tre[p].add+=w;
return;
}
push_down(p);
int mid=tr+tl>>1;
if(l<=mid) update(lch,l,r,w);
if(r>mid) update(rch,l,r,w);
push_up(p);
return;
}
inline int query(int p,int l,int r){
if(l<=tl&&tr<=r) return tre[p].max;
int ans=0;
push_down(p);
int mid=tr+tl>>1;
if(l<=mid) ans=max(ans,query(lch,l,r));
if(r>mid) ans=max(ans,query(rch,l,r));
return ans;
}
#undef lch
#undef rch
#undef tr
#undef tl
inline void Cover(int u,int v,int w){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cover(1,dfn[top[u]],dfn[u],w);
u=faz[top[u]];
}
if(u==v) return;
if(dep[u]>dep[v]) swap(u,v);
cover(1,dfn[u]+1,dfn[v],w);
return;
}
inline void Add(int u,int v,int w){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(1,dfn[top[u]],dfn[u],w);
u=faz[top[u]];
}
if(u==v) return;
if(dep[u]>dep[v]) swap(u,v);
update(1,dfn[u]+1,dfn[v],w);
return;
}
inline int Query(int u,int v){
int ans=-INF;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=max(ans,query(1,dfn[top[u]],dfn[u]));
u=faz[top[u]];
}
if(u==v) return ans;
if(dep[u]>dep[v]) swap(u,v);
ans=max(ans,query(1,dfn[u]+1,dfn[v]));
return ans;
}
signed main(){
// freopen("moon.in","r",stdin);
// freopen("moon.out","w",stdout);
n=in;
for(int i=1;i<n;++i){
int u=in,v=in,w=in;
add(u,v);
add(v,u);
to1[i]=u;
to2[i]=v;
wei[i]=w;
}
DFS1(0,1);
DFS2(1,1);
push_road();
build(1,1,n);
scanf("%s",q);
while(q[0]!='S'){
if(q[1]=='h'){
int k=in,w=in;
cover(1,dfn[dwn[k]],dfn[dwn[k]],w);
}else if(q[1]=='o'){
int u=in,v=in,w=in;
Cover(u,v,w);
}else if(q[1]=='d'){
int u=in,v=in,w=in;
Add(u,v,w);
}else if(q[1]=='a'){
int u=in,v=in;
printf("%lld\n",Query(u,v));
}scanf("%s",q);
}
return 0;
}
另外的DFS1就下放的代碼,我先咕了~