社区讨论
0pts过样例求调,(悬6关)
P4315月下“毛景树”参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mdpmmali
- 此快照首次捕获于
- 2025/07/30 15:10 7 个月前
- 此快照最后确认于
- 2025/11/04 03:28 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5;
struct node
{
int nxt,id,w;
};
struct segtree
{
int l,r;
int chtag,adtag;
int maxx;
}tree[4*N+5];
int n;
int a[N+5];
int s[N+5];
int fa[N+5],dep[N+5],siz[N+5],son[N+5];
int dfncnt,dfn[N+5],seg[N+5],tp[N+5];
vector<node>to[N+5];
void dfs1(int anc,int root)
{
int maxx=0;
fa[root]=anc;
dep[root]=dep[anc]+1;
siz[root]=1;
for(auto v:to[root])
{
if(v.nxt==anc) continue;
s[v.id]=v.nxt; //第v.id条边的权值在v.nxt(儿子)上
a[v.nxt]=v.w; //边权转点权
dfs1(root,v.nxt);
siz[root]+=siz[v.nxt];
if(siz[v.nxt]>maxx)
{
maxx=siz[v.nxt];
son[root]=v.nxt;
}
}
return ;
}
void dfs2(int root,int topp)
{
tp[root]=topp;
dfn[root]=++dfncnt;
seg[dfncnt]=root;
if(!son[root]) return ;
dfs2(son[root],topp);
for(auto v:to[root])
{
if(v.nxt==fa[root] || v.nxt==son[root]) continue;
dfs2(v.nxt,v.nxt);
}
return ;
}
void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r;
if(l==r)
{
tree[k].maxx=a[seg[l]];
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
return ;
}
void push_down(int k)
{
if(tree[k].chtag!=-1)
{
int tag=tree[k].chtag;
tree[k].chtag=-1;
tree[k<<1].chtag=tag;
tree[k<<1|1].chtag=tag;
tree[k<<1].maxx=tag;
tree[k<<1|1].maxx=tag;
}
int tag=tree[k].adtag;
tree[k].adtag=0;
tree[k<<1].adtag+=tag;
tree[k<<1|1].adtag+=tag;
tree[k<<1].maxx+=tag;
tree[k<<1|1].maxx+=tag;
return ;
}
void change(int k,int l,int r,int x)
{
if(tree[k].l>=l && tree[k].r<=r)
{
tree[k].chtag=x;
tree[k].adtag=0;
tree[k].maxx=x;
return ;
}
push_down(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(mid>=l)
change(k<<1,l,r,x);
if(mid+1<=r)
change(k<<1|1,l,r,x);
tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
return;
}
void add(int k,int l,int r,int x)
{
// cout<<k<<" "<<tree[k].l<<" "<<tree[k].r<<"\n";
if(tree[k].l>=l && tree[k].r<=r)
{
tree[k].maxx+=x;
tree[k].adtag+=x;
return ;
}
push_down(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(mid>=l)
add(k<<1,l,r,x);
if(mid+1<=r)
add(k<<1|1,l,r,x);
tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
return ;
}
int ask(int k,int l,int r)
{
// cout<<tree[k].l<<" "<<tree[k].r<<"\n";
int maxx=0;
if(tree[k].l>=l && tree[k].r<=r)
return tree[k].maxx;
int mid=(tree[k].l+tree[k].r)>>1;
if(mid>=l)
maxx=max(maxx,ask(k<<1,l,r));
if(mid+1<=r)
maxx=max(maxx,ask(k<<1|1,l,r));
return maxx;
}
int ask_path(int xx,int yy)
{
int ans=0;
int x=xx,y=yy;
while(tp[x]!=tp[y])
{
// cout<<x<<" "<<y<<"\n";
if(dep[tp[x]]<dep[tp[y]])
swap(x,y);
ans=max(ans,ask(1,dfn[tp[x]],dfn[x]));
x=fa[tp[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ans=max(ans,ask(1,dfn[x]+1,dfn[y]));
return ans;
}
void change_path(int xx,int yy,int cg)
{
int ans=0;
int x=xx,y=yy;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]])
swap(x,y);
change(1,dfn[tp[x]],dfn[x],cg);
x=fa[tp[x]];
}
if(dep[x]>dep[y])
swap(x,y);
change(1,dfn[x]+1,dfn[y],cg);
return ;
}
void add_path(int xx,int yy,int cg)
{
int ans=0;
int x=xx,y=yy;
while(tp[x]!=tp[y])
{
// cout<<x<<" "<<y<<"\n";
if(dep[tp[x]]<dep[tp[y]])
swap(x,y);
add(1,dfn[tp[x]],dfn[x],cg);
x=fa[tp[x]];
}
if(dep[x]>dep[y])
swap(x,y);
add(1,dfn[x]+1,dfn[y],cg);
return ;
}
main()
{
cin>>n;
for(int i=1;i<=n-1;i++)
{
int u,v,w;
cin>>u>>v>>w;
to[u].push_back({v,i,w}),to[v].push_back({u,i,w});
}
dfs1(1,1);
dfs2(1,1);
build(1,1,n);
while(true)
{
int x,y,z;
string op;
cin>>op;
// cout<<op<<"\n";
if(op[0]=='S') break;
if(op[0]=='M')
{
// cout<<"jkfsdjkfsdjklfjksdl\n";
cin>>x>>y;
cout<<ask_path(x,y)<<"\n";
}
else if(op=="Cover")
{
cin>>x>>y>>z;
change_path(x,y,z);
}
else if(op=="Change")
{
cin>>x>>y;
change(1,dfn[s[x]],dfn[s[x]],y);
}
else
{
// cout<<"fjfjfjjfdjfdj\n";
cin>>x>>y>>z;
add_path(x,y,z);
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...