一开始看到这题,决定用树剖(题目标签也有)
然后简单看了会题面,把每个操作都分析了分析,然后摸了会鱼(还没做)当时时间20:48(有和朋友的qq聊天记录)
然后过了会我决定 不再颓废 ,然后打开了这道题开始写,因为我好久没写树剖基本都忘了,是思考着写的很慢。中间遇到了很多问题,但我都一一想到了解决方案(而且确实是我目前的解法)
到22:21,我的那位朋友已经切掉了,但我才写了三分之二的源代码。。。
到了23:29,我开始正式调试,大概有以下几个小错误(大体按顺序来)
没有剖链的dfs就先建树(23:28)
读入出错(23:29)
线段树查询写错(23:31)
全部的线段树操作都没下发标记(23:36)
线段树的修改操作没把维护的 maxn
修改(从上一个到这个花了半小时,此时23:59)
到这里我的样例就过了,我就第一次提交了此题(测评时间是23:59:40),全WA了
作为曾经的树剖人,我先想了几个问题:
初值
数据范围
输出格式
是不是理解错题目了
然而其实到最后上面几条都没错。。。
然后下载了第一个测试点(大样例),输入1795KB,人已经崩了
然后用文件输入输出+对拍拍了拍发现没拍出错(0:06),然后又提交一遍,发现还是WA
然后我才发现我对拍错了
在我的输出和测试点输出的172不一样,显然出错了
当时看了好久都没看出来,已经准备重开了(0:14)
后来,我就用我最笨也最容易查出错来的方法:
保证你的思路绝对对
每次重构一个函数(不是抄,是按思路重写),先对照看看两次的想法一不一样。如果写的一样,代入到你的代码中看看是不是有错(其实这个已经没必要了,但我真的怕我眼睛少瞅一个字母);如果不一样,重点研究两个想法的不同之处,然后做哪个对的选择
我确实这样做了,我也确实用这样的方法A了
但是,我的 push_down
函数最长最难想,当时我写的时候就想了很久,我就把它作为最后一个重构的,希望能够不重构它就能A掉
很可惜,我错了。就只有 push_down
有错误。。。
所以说,要这样调,先调你觉得最可能错的或者思路最麻烦的,接着是你没有把握的,最后才是你最有把握的
最终我重构完 push_down
是(0:59:50)
然后我又经过了几次 MLE(之前开的数组大小其实是对的,但我怕错提了十倍,于是乎) TLE(我调测试点的 freopen
没删) 才挺过来,A了(1:03:56)
成了这副德行:
更改后代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#define inf 9223372036854775807
using namespace std;
const int MAXN=1e5+9,MAXM=2e5+9,MAXT=4e59;
typedef long long ll;
struct Tree{
int ls,rs;
ll tag=0,tagk,w,maxn;
}tree[MAXT];
#define ls(x) tree[x].ls
#define rs(x) tree[x].rs
#define tag(x) tree[x].tag
#define tagk(x) tree[x].tagk
#define w(x) tree[x].w
#define maxn(x) tree[x].maxn
int num_tree=1;
struct Edge{
int nxt,to,w;
}edge[MAXM];
int num_edge=0,head[MAXN];
int dw[MAXN];
struct Node{
int from,to;
}edgeid[MAXM];
int num_T=0,dep[MAXN],siz[MAXN],top[MAXN],f[MAXN],heavy[MAXN],ys[MAXN],Tid[MAXN];
int n;
void push_up(int now){
w(now)=w(ls(now))+w(rs(now));
maxn(now)=max(maxn(ls(now)),maxn(rs(now)));
}void push_down(int now,int l,int r){
int mid=(l+r)>>1;
if(tag(now)){
w(ls(now))=(mid-l+1)*tag(now);
w(rs(now))=(r-mid)*tag(now);
maxn(ls(now))=tag(now);
maxn(rs(now))=tag(now);
if(tag(ls(now))){
tag(ls(now))=tag(now);
}else{
if(tagk(ls(now)))tagk(ls(now))=0;
tag(ls(now))=tag(now);
}if(tag(rs(now))){
tag(rs(now))=tag(now);
}else{
if(tagk(rs(now)))tagk(rs(now))=0;
tag(rs(now))=tag(now);
}tag(now)=0;
}else{
if(!tagk(now))return;
w(ls(now))+=(mid-l+1)*tagk(now);
w(rs(now))+=(r-mid)*tagk(now);
maxn(ls(now))+=tagk(now);
maxn(rs(now))+=tagk(now);
if(tag(ls(now)))tag(ls(now))+=tagk(now);
else tagk(ls(now))+=tagk(now);
if(tag(rs(now)))tag(rs(now))+=tagk(now);
else tagk(rs(now))+=tagk(now);
tagk(now)=0;
}
}void build(int now,int l,int r){
if(l==r){
w(now)=ys[l];
maxn(now)=ys[l];
return;
}int mid=(l+r)>>1;
ls(now)=++num_tree;
rs(now)=++num_tree;
build(ls(now),l,mid);
build(rs(now),mid+1,r);
push_up(now);
}void update1(int now,int l,int r,int lx,int rx,ll k){
if(lx<=l&&r<=rx){
w(now)=(r-l+1)*k;
maxn(now)=k;
if(tagk(now))tagk(now)=0;
tag(now)=k;
return;
}int mid=(l+r)>>1;
push_down(now,l,r);
if(lx<=mid)update1(ls(now),l,mid,lx,rx,k);
if(rx>mid)update1(rs(now),mid+1,r,lx,rx,k);
push_up(now);
}void update2(int now,int l,int r,int lx,int rx,ll k){
if(lx<=l&&r<=rx){
w(now)+=(r-l+1)*k;
maxn(now)+=k;
if(tag(now))tag(now)+=k;
else tagk(now)+=k;
return;
}int mid=(l+r)>>1;
push_down(now,l,r);
if(lx<=mid)update2(ls(now),l,mid,lx,rx,k);
if(rx>mid)update2(rs(now),mid+1,r,lx,rx,k);
push_up(now);
}ll query(int now,int l,int r,int lx,int rx){
if(lx<=l&&r<=rx){
return maxn(now);
}int mid=(l+r)>>1;
ll ans=-inf;
push_down(now,l,r);
if(lx<=mid)ans=max(ans,query(ls(now),l,mid,lx,rx));
if(rx>mid)ans=max(ans,query(rs(now),mid+1,r,lx,rx));
return ans;
}void add_edge(int from,int to,int w){
edge[++num_edge]=(Edge){head[from],to,w};
head[from]=num_edge;
}void dfs1(int now,int fa){
f[now]=fa;
siz[now]=1;
dep[now]=dep[fa]+1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa)continue;
dfs1(to,now);
siz[now]+=siz[to];
dw[to]=edge[i].w;
if(siz[heavy[now]]<siz[to])heavy[now]=to;
}
}void dfs2(int now,int tp){
top[now]=tp;
Tid[now]=++num_T;
ys[num_T]=dw[now];
if(heavy[now])dfs2(heavy[now],tp);
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==f[now]||to==heavy[now])continue;
dfs2(to,to);
}
}void Tupdate1(int x,ll k){
int id=edgeid[x].to;
if(dep[edgeid[x].from]>dep[edgeid[x].to])id=edgeid[x].from;
update1(1,1,n,Tid[id],Tid[id],k);
}void Tupdate2(int x,int y,ll k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update1(1,1,n,Tid[top[x]],Tid[x],k);
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
update1(1,1,n,Tid[x]+1,Tid[y],k);
}void Tupdate3(int x,int y,ll k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update2(1,1,n,Tid[top[x]],Tid[x],k);
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
update2(1,1,n,Tid[x]+1,Tid[y],k);
}ll Tquery(int x,int y){
ll ans=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query(1,1,n,Tid[top[x]],Tid[x]));
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
ans=max(ans,query(1,1,n,Tid[x]+1,Tid[y]));
return ans;
}inline ll read(){
register ll x=0,f=1;register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}int main(){
// freopen("P4315_1.in","r",stdin);
// freopen("P4315_1t.out","w",stdout);
n=read();
for(int i=1;i<=n-1;i++){
ll u,v,w;
u=read();v=read();w=read();
add_edge(u,v,w);
add_edge(v,u,w);
edgeid[i].from=u;
edgeid[i].to=v;
}dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(1){
string op;
cin>>op;
ll x,y,k;
if(op=="Stop")break;
if(op=="Change"){
x=read();k=read();
Tupdate1(x,k);
}if(op=="Cover"){
x=read();y=read();k=read();
Tupdate2(x,y,k);
}if(op=="Add"){
x=read();y=read();k=read();
Tupdate3(x,y,k);
}if(op=="Max"){
x=read();y=read();
printf("%lld\n",Tquery(x,y));
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
带调试的(我的调试全过程)
#include<iostream>
#include<cstdio>
#include<cmath>
#define inf 9223372036854775807
using namespace std;
const int MAXN=1e5+9,MAXM=2e5+9,MAXT=4e5+9;
typedef long long ll;
struct Tree{
int ls,rs;
ll tag=0,tagk,w,maxn;
}tree[MAXT];
#define ls(x) tree[x].ls
#define rs(x) tree[x].rs
#define tag(x) tree[x].tag
#define tagk(x) tree[x].tagk
#define w(x) tree[x].w
#define maxn(x) tree[x].maxn
int num_tree=1;
struct Edge{
int nxt,to,w;
}edge[MAXM];
int num_edge=0,head[MAXN];
int dw[MAXN];
struct Node{
int from,to;
}edgeid[MAXM];
int num_T=0,dep[MAXN],siz[MAXN],top[MAXN],f[MAXN],heavy[MAXN],ys[MAXN],Tid[MAXN];
int n;
//void push_up(int now){
// w(now)=w(ls(now))+w(rs(now));
// maxn(now)=max(maxn(ls(now)),maxn(rs(now)));
//}
void push_up(int now){
w(now)=w(ls(now))+w(rs(now));
maxn(now)=max(maxn(ls(now)),maxn(rs(now)));
}
//void push_down(int now,int l,int r){
//// cout<<"push_down the tag of "<<l<<"~"<<r<<endl;
// if(tag(now)){//tag非0
// int mid=(l+r)>>1;
// w(ls(now))=(mid-l+1)*tag(now);
// w(rs(now))=(r-mid)*tag(now);
// maxn(ls(now))=tag(now);
// maxn(rs(now))=tag(now);
// if(tag(ls(now))){
// tag(ls(now))=tag(now);
// }else{
// if(!tagk(ls(now))){//有tagk
// tag(ls(now))=tag(now);
// tagk(ls(now))=0;
// }else tag(ls(now))=tag(now);
// }if(tag(rs(now))){
// tag(rs(now))=tag(now);
// }else{
// if(!tagk(rs(now))){//有tagk
// tag(rs(now))=tag(now);
// tagk(rs(now))=0;
// }else tag(rs(now))=tag(now);
// }tag(now)=0;
// }else{
// if(!tagk(now))return;
// int mid=(l+r)>>1;
// w(ls(now))+=(mid-l+1)*tagk(now);
// w(rs(now))+=(r-mid)*tagk(now);
// maxn(ls(now))+=tagk(now);
// maxn(rs(now))+=tagk(now);
// if(tag(ls(now))){
// tag(ls(now))+=tagk(now);
// }else{
// tagk(ls(now))+=tagk(now);
// }if(tag(rs(now))){
// tag(rs(now))+=tagk(now);
// }else{
// tagk(rs(now))+=tagk(now);
// }tagk(now)=0;
// }
//}
void push_down(int now,int l,int r){
int mid=(l+r)>>1;
if(tag(now)){
w(ls(now))=(mid-l+1)*tag(now);
w(rs(now))=(r-mid)*tag(now);
maxn(ls(now))=tag(now);
maxn(rs(now))=tag(now);
if(tag(ls(now))){
tag(ls(now))=tag(now);
}else{
if(tagk(ls(now)))tagk(ls(now))=0;
tag(ls(now))=tag(now);
}if(tag(rs(now))){
tag(rs(now))=tag(now);
}else{
if(tagk(rs(now)))tagk(rs(now))=0;
tag(rs(now))=tag(now);
}tag(now)=0;
}else{
if(!tagk(now))return;
w(ls(now))+=(mid-l+1)*tagk(now);
w(rs(now))+=(r-mid)*tagk(now);
maxn(ls(now))+=tagk(now);
maxn(rs(now))+=tagk(now);
if(tag(ls(now)))tag(ls(now))+=tagk(now);
else tagk(ls(now))+=tagk(now);
if(tag(rs(now)))tag(rs(now))+=tagk(now);
else tagk(rs(now))+=tagk(now);
tagk(now)=0;
}
}
//void build(int now,int l,int r){
// if(l==r){
// w(now)=ys[l];
// maxn(now)=ys[l];
// return;
// }int mid=(l+r)>>1;
// ls(now)=++num_tree;
// rs(now)=++num_tree;
// build(ls(now),l,mid);
// build(rs(now),mid+1,r);
// push_up(now);
//}
void build(int now,int l,int r){
if(l==r){
w(now)=ys[l];
maxn(now)=ys[l];
return;
}int mid=(l+r)>>1;
ls(now)=++num_tree;
rs(now)=++num_tree;
build(ls(now),l,mid);
build(rs(now),mid+1,r);
push_up(now);
}
//void update1(int now,int l,int r,int lx,int rx,ll k){//硬赋值
////cout<<"check"<<l<<"~"<<r<<" and "<<lx<<"~"<<rx<<endl;
// if(lx<=l&&r<=rx){
//// cout<<"value is "<<w(now)<<endl;
// w(now)=(r-l+1)*k;
// maxn(now)=k;
// if(tagk(now))tagk(now)=0;
// tag(now)=k;
//// cout<<"give"<<l<<"~"<<r<<" tag is "<<k<<" all value is"<<w(now)<<endl;
// return;
// }int mid=(l+r)>>1;
// push_down(now,l,r);
// if(lx<=mid)update1(ls(now),l,mid,lx,rx,k);
// if(rx>mid)update1(rs(now),mid+1,r,lx,rx,k);
// push_up(now);
//}
void update1(int now,int l,int r,int lx,int rx,ll k){
if(lx<=l&&r<=rx){
w(now)=(r-l+1)*k;
maxn(now)=k;
if(tagk(now))tagk(now)=0;
tag(now)=k;
return;
}int mid=(l+r)>>1;
push_down(now,l,r);
if(lx<=mid)update1(ls(now),l,mid,lx,rx,k);
if(rx>mid)update1(rs(now),mid+1,r,lx,rx,k);
push_up(now);
}
//void update2(int now,int l,int r,int lx,int rx,ll k){//软赋值
// if(lx<=l&&r<=rx){
// w(now)+=(r-l+1)*k;
// maxn(now)+=k;
// if(tag(now))tag(now)+=k;
// else tagk(now)+=k;
// return;
// }int mid=(l+r)/2;
// push_down(now,l,r);
// if(lx<=mid)update2(ls(now),l,mid,lx,rx,k);
// if(rx>mid)update2(rs(now),mid+1,r,lx,rx,k);
// push_up(now);
//}
void update2(int now,int l,int r,int lx,int rx,ll k){
if(lx<=l&&r<=rx){
w(now)+=(r-l+1)*k;
maxn(now)+=k;
if(tag(now))tag(now)+=k;
else tagk(now)+=k;
return;
}int mid=(l+r)>>1;
push_down(now,l,r);
if(lx<=mid)update2(ls(now),l,mid,lx,rx,k);
if(rx>mid)update2(rs(now),mid+1,r,lx,rx,k);
push_up(now);
}
//ll query(int now,int l,int r,int lx,int rx){
// if(lx<=l&&r<=rx){
// return maxn(now);
// }int mid=(l+r)>>1;
// ll ans=-inf;
// push_down(now,l,r);
//// cout<<"now"<<now<<"ls:"<<ls(now)<<" rs:"<<rs(now)<<" l,r:"<<l<<"~"<<r<<" to "<<lx<<"~"<<rx<<endl;
// if(lx<=mid)ans=max(ans,query(ls(now),l,mid,lx,rx));
// if(rx>mid)ans=max(ans,query(rs(now),mid+1,r,lx,rx));
// return ans;
//}
ll query(int now,int l,int r,int lx,int rx){
if(lx<=l&&r<=rx){
return maxn(now);
}int mid=(l+r)>>1;
ll ans=-inf;
push_down(now,l,r);
if(lx<=mid)ans=max(ans,query(ls(now),l,mid,lx,rx));
if(rx>mid)ans=max(ans,query(rs(now),mid+1,r,lx,rx));
return ans;
}
/*
如果当前tag=0,那么tagk=k即可
如果tag!=0,那么tag=k+tag,tagk=0
push_down看tag是否为0,如果为0下发tagk,如果不为0下发tag
*/
//void add_edge(int from,int to,int w){
// edge[++num_edge]=(Edge){head[from],to,w};
// head[from]=num_edge;
//}
void add_edge(int from,int to,int w){
edge[++num_edge]=(Edge){head[from],to,w};
head[from]=num_edge;
}
//void dfs1(int now,int fa){
// f[now]=fa;
// siz[now]=1;
// dep[now]=dep[fa]+1;
// for(int i=head[now];i;i=edge[i].nxt){
// int to=edge[i].to;
// if(to==fa)continue;
// dfs1(to,now);
// siz[now]+=siz[to];
// dw[to]=edge[i].w;
// if(siz[heavy[now]]<siz[to])heavy[now]=to;
// }
//}
void dfs1(int now,int fa){
f[now]=fa;
siz[now]=1;
dep[now]=dep[fa]+1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa)continue;
dfs1(to,now);
siz[now]+=siz[to];
dw[to]=edge[i].w;
if(siz[heavy[now]]<siz[to])heavy[now]=to;
}
}
//void dfs2(int now,int tp){
// top[now]=tp;
// Tid[now]=++num_T;
// ys[num_T]=dw[now];
//// cout<<"now:"<<now<<endl;
// if(heavy[now])dfs2(heavy[now],tp);
// for(int i=head[now];i;i=edge[i].nxt){
// int to=edge[i].to;
// if(to==f[now]||to==heavy[now])continue;
// dfs2(to,to);
// }
//}
void dfs2(int now,int tp){
top[now]=tp;
Tid[now]=++num_T;
ys[num_T]=dw[now];
if(heavy[now])dfs2(heavy[now],tp);
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==f[now]||to==heavy[now])continue;
dfs2(to,to);
}
}
//void Tupdate1(int x,ll k){
// int id=edgeid[x].from;
// if(dep[edgeid[x].to]>dep[edgeid[x].from])id=edgeid[x].to;
// update1(1,1,n,Tid[id],Tid[id],k);
//}
void Tupdate1(int x,ll k){
int id=edgeid[x].to;
if(dep[edgeid[x].from]>dep[edgeid[x].to])id=edgeid[x].from;
update1(1,1,n,Tid[id],Tid[id],k);
}
//void Tupdate2(int x,int y,ll k){
// while(top[x]!=top[y]){
// if(dep[top[x]]<dep[top[y]])swap(x,y);
//// cout<<">>"<<top[x]<<"~"<<x<<endl;
// update1(1,1,n,Tid[top[x]],Tid[x],k);
//// cout<<"Zhou"<<endl;
// x=f[top[x]];
// }if(dep[x]>dep[y])swap(x,y);
//// cout<<">>"<<x+1<<"~"<<y<<endl;
// update1(1,1,n,Tid[x]+1,Tid[y],k);
//}
void Tupdate2(int x,int y,ll k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update1(1,1,n,Tid[top[x]],Tid[x],k);
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
update1(1,1,n,Tid[x]+1,Tid[y],k);
}
//void Tupdate3(int x,int y,ll k){
// while(top[x]!=top[y]){
// if(dep[top[x]]<dep[top[y]])swap(x,y);
// update2(1,1,n,Tid[top[x]],Tid[x],k);
// x=f[top[x]];
// }if(dep[x]>dep[y])swap(x,y);
// update2(1,1,n,Tid[x]+1,Tid[y],k);
//}
void Tupdate3(int x,int y,ll k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update2(1,1,n,Tid[top[x]],Tid[x],k);
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
update2(1,1,n,Tid[x]+1,Tid[y],k);
}
//ll Tquery(int x,int y){
// ll ans=-inf;
// while(top[x]!=top[y]){
// if(dep[top[x]]<dep[top[y]])swap(x,y);
// ans=max(ans,query(1,1,n,Tid[top[x]],Tid[x]));
//// cout<<"AS"<<endl;
// x=f[top[x]];
// }if(dep[x]>dep[y])swap(x,y);
// ans=max(ans,query(1,1,n,Tid[x]+1,Tid[y]));
// return ans;
//}
ll Tquery(int x,int y){
ll ans=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query(1,1,n,Tid[top[x]],Tid[x]));
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
ans=max(ans,query(1,1,n,Tid[x]+1,Tid[y]));
return ans;
}
//inline ll read(){
// register ll x=0;register bool f=0;register char ch=getchar();
// while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
// while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
// return x*(f?-1:1);
//}
inline ll read(){
register ll x=0,f=1;register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//int main(){
// freopen("P4315_1.in","r",stdin);
// freopen("P4315_1t.out","w",stdout);
// n=read();
// for(int i=1;i<=n-1;i++){
// int u,v,w;
// u=read();v=read();w=read();
// add_edge(u,v,w);
// add_edge(v,u,w);
// edgeid[i].from=u;
// edgeid[i].to=v;
// }dfs1(1,0);
// dfs2(1,1);
// build(1,1,n);
//// for(int i=1;i<=n;i++){
//// cout<<"Tid["<<i<<"]="<<Tid[i]<<endl;
//// cout<<"dw["<<i<<"]="<<dw[i]<<endl;
//// cout<<"ys["<<i<<"]="<<ys[i]<<endl;
//// cout<<"top["<<i<<"]="<<top[i]<<endl;
//// cout<<"ys["<<i<<"]="<<ys[i]<<endl;
//// }
//// printf("%lld\n",Tquery(1,4));
// while(1){
// string ch;
// int x,y;
// ll w;
// cin>>ch;
// if(ch[0]=='S')break;
// if(ch[0]=='C'){
// if(ch[1]=='h'){
// x=read();w=read();
// Tupdate1(x,w);
// }else{
// x=read();y=read();w=read();
// Tupdate2(x,y,w);
// }
// }if(ch[0]=='A'){
// x=read();y=read();w=read();
// Tupdate3(x,y,w);
// }if(ch[0]=='M'){
// x=read();y=read();
// printf("**%lld\n",Tquery(x,y));
// }
// }
// fclose(stdin);
// fclose(stdout);
// return 0;
//}
int main(){
// freopen("P4315_1.in","r",stdin);
// freopen("P4315_1t.out","w",stdout);
n=read();
for(int i=1;i<=n-1;i++){
ll u,v,w;
u=read();v=read();w=read();
add_edge(u,v,w);
add_edge(v,u,w);
edgeid[i].from=u;
edgeid[i].to=v;
}dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(1){
string op;
cin>>op;
ll x,y,k;
if(op=="Stop")break;
if(op=="Change"){
x=read();k=read();
Tupdate1(x,k);
}if(op=="Cover"){
x=read();y=read();k=read();
Tupdate2(x,y,k);
}if(op=="Add"){
x=read();y=read();k=read();
Tupdate3(x,y,k);
}if(op=="Max"){
x=read();y=read();
printf("%lld\n",Tquery(x,y));
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
436行太刺激了......总字数好像是9368(我的dev卡bug了不显示字数,我用wps看的字数),带空格的话是10193
我又花了将近半个小时写了这篇文章,回顾我的历史
我现在已经感觉到肚子疼了(肝疼)。。。