社区讨论
妹子刚学OI 树剖10pts在线求条
P4315月下“毛景树”参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lr64btkv
- 此快照首次捕获于
- 2024/01/09 16:57 2 年前
- 此快照最后确认于
- 2024/01/09 19:13 2 年前
调了一天了,真的调不出来了QAQ
CPP#include<iostream>
#define int long long
#define C 2147483647
#define lc p<<1
#define rc (p<<1)+1
using namespace std;
struct Tr{
int l,r,maxn,cov,chan;
}tr[800005];
struct Edge{
int l,w,nxt;
}edges[200005];
int n,tt,head[200005],num[200005];
int siz[200005],son[200005],fas[200005],dep[200005];
int cnt,top[200005],id[200005],di[200005],val[200005];
void add_edge(int f,int l,int w){
tt+=1;
edges[tt]={l,w,head[f]};
head[f]=tt;
}
void dfs1(int x,int fa){
fas[x]=fa,dep[x]=dep[fa]+1,siz[x]=1;
for(int i=head[x];i;i=edges[i].nxt){
int l=edges[i].l;
if(l==fa) continue;
dfs1(l,x);
siz[x]+=siz[l],num[l]=edges[i].w;
if(siz[l]>siz[son[x]]) son[x]=l;
}
}
void dfs2(int x,int tot){
cnt+=1,id[x]=cnt,di[cnt]=x,val[cnt]=num[x],top[x]=tot;
if(!son[x]) return;
dfs2(son[x],tot);
for(int i=head[x];i;i=edges[i].nxt){
int l=edges[i].l;
if(l==son[x]||l==fas[x]) continue;
dfs2(l,l);
}
}
void pushup(int p){
tr[p].maxn=max(tr[lc].maxn,tr[rc].maxn);
}
void pushdown(int p){
if(tr[p].cov!=-1){
tr[lc].maxn=tr[p].cov;
tr[rc].maxn=tr[p].cov;
tr[lc].cov=tr[p].cov;
tr[rc].cov=tr[p].cov;
}
tr[lc].maxn+=tr[p].chan;
tr[rc].maxn+=tr[p].chan;
tr[lc].chan+=tr[p].chan;
tr[rc].chan+=tr[p].chan;
tr[p].chan=0,tr[p].cov=-1;
}
void build(int l,int r,int p){
tr[p]={l,r,0,-1,0};
if(l==r){
tr[p].maxn=val[l];
return;
}
int m=(l+r)/2;
build(l,m,lc);build(m+1,r,rc);
pushup(p);
}
void update_cov(int l,int r,int p,int k){
pushdown(p);
if(l<=tr[p].l&&tr[p].r<=r){
tr[p].cov=k,tr[p].chan=0,tr[p].maxn=k;
return;
}
int m=(tr[p].l+tr[p].r)/2;
if(l<=m) update_cov(l,r,lc,k);
if(m<r) update_cov(l,r,rc,k);
pushup(p);
}
void update_add(int l,int r,int p,int k){
pushdown(p);
if(l<=tr[p].l&&tr[p].r<=r){
tr[p].chan+=k,tr[p].maxn+=k;
return;
}
int m=(tr[p].l+tr[p].r)/2;
if(l<=m) update_add(l,r,lc,k);
if(m<r) update_add(l,r,rc,k);
pushup(p);
}
void update_self_cov(int x,int k){
update_cov(id[x],id[x],1,k);
}
void update_tr_cov(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update_cov(id[top[x]],id[x],1,k);
x=fas[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
if(x==y) return;
update_cov(id[son[y]],id[x],1,k);
}
void update_tr_add(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update_add(id[top[x]],id[x],1,k);
x=fas[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
if(x==y) return;
update_add(id[son[y]],id[x],1,k);
}
int find(int l,int r,int p){
pushdown(p);
if(l<=tr[p].l&&tr[p].r<=r) return tr[p].maxn;
int m=(tr[p].l+tr[p].r)/2,an=0;
if(l<=m) an=max(an,find(l,r,lc));
if(m<r) an=max(an,find(l,r,rc));
return an;
}
int find_tr(int x,int y){
int an=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
an=max(an,find(id[top[x]],id[x],1));
x=fas[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
if(x==y) return an;
an=max(an,find(id[son[y]],id[x],1));
return an;
}
signed main(){
string s;
int f,l,w;
ios::sync_with_stdio(false);
cin.tie();cout.tie();
cin>>n;
for(int i=1;i<n;i++){
cin>>f>>l>>w;
add_edge(f,l,w);
add_edge(l,f,w);
}
dfs1(1,0);dfs2(1,1);build(1,n,1);
while(true){
cin>>s;
if(s=="Stop") break;
else if(s=="Max"){
cin>>f>>l;
if(f==l) cout<<0<<endl;
else cout<<find_tr(f,l)<<endl;
}
else if(s=="Change"){
cin>>f>>l;
int awa=edges[f*2].l,ouo=edges[f*2-1].l;
if(fas[ouo]==awa) swap(ouo,awa);
update_self_cov(awa,l);
}
else if(s=="Cover"){
cin>>f>>l>>w;
if(f==l) continue;
update_tr_cov(f,l,w);
}
else if(s=="Add"){
cin>>f>>l>>w;
if(f==l) continue;
update_tr_add(f,l,w);
}
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...