[国家集训队]旅游
很简单一道题,评紫实在是有点暴殄天物。边权下放到点权然后查询时注意不要查找lca的值即可。本来以为在区间取反的基础上还有个区间加所以双lazy还有点麻烦时,突然发现它似乎只有单点修改。
唯一不好的事就是我把树剖的板子打错了。应该判的是top的深度大小,然后我tmd竟然把这茬给忘了。于是调了两个小时,最后在翻原来树剖的代码时偶然发现。操。
#include<cstdio>
//#define zczc
const int N=200010;
const int inf=1e9;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int op(){
char w[10];scanf("%s",w);
switch(w[0]){
case 'C':return 0;break;
case 'N':return 1;break;
case 'S':return 2;break;
case 'M':return w[1]=='A'?3:4;break;
}
}
inline void swap(int &s1,int &s2){
int s3=s1;s1=s2;s2=s3;return;
}
inline int max(int s1,int s2){
return s1<s2?s2:s1;
}
inline int min(int s1,int s2){
return s1<s2?s1:s2;
}
int m,n,a[N];
struct edge{
int t,v,next;
}e[N<<1];
int esum,head[N];
inline void add(int fr,int to,int val){
e[++esum]=(edge){to,val,head[fr]};head[fr]=esum;
}
int d[N],size[N],son[N],f[N];
void dfs1(int wh,int fa){
size[wh]=1;d[wh]=d[fa]+1;f[wh]=fa;
for(int i=head[wh],th;i;i=e[i].next){
if((th=e[i].t)==fa)continue;
dfs1(th,wh);size[wh]+=size[th];
if(size[th]>size[son[wh]])son[wh]=th;
}
}
int cnt,id[N],top[N],fir[N];
void dfs2(int wh,int ntop){
id[wh]=++cnt;top[wh]=ntop;
if(son[wh])dfs2(son[wh],ntop);
for(int i=head[wh],th;i;i=e[i].next){
if((th=e[i].t)==f[wh]||th==son[wh])continue;
dfs2(th,th);
}
}
#define lc (wh<<1)
#define rc (wh<<1|1)
#define mid (t[wh].l+t[wh].r>>1)
#define num (t[wh].r-t[wh].l+1)
struct node{
int l,r,sum,maxn,minn;
bool lazy;
}t[N<<2];
inline void pushup(int wh){
t[wh].sum=t[lc].sum+t[rc].sum;
t[wh].maxn=max(t[lc].maxn,t[rc].maxn);
t[wh].minn=min(t[lc].minn,t[rc].minn);
}
inline void pushnow(int wh){
swap(t[wh].maxn,t[wh].minn);
t[wh].lazy^=1;t[wh].maxn*=-1;
t[wh].minn*=-1;t[wh].sum*=-1;
}
inline void pushdown(int wh){
if(!t[wh].lazy)return;t[wh].lazy=false;
pushnow(lc);pushnow(rc);
}
inline void build(int wh,int l,int r){
t[wh].l=l,t[wh].r=r;
if(l==r){t[wh].maxn=t[wh].minn=t[wh].sum=fir[l];return;}
build(lc,l,mid);build(rc,mid+1,r);pushup(wh);
}
inline void update(int wh,int pl,int val){
if(t[wh].l==t[wh].r){t[wh].sum=t[wh].maxn=t[wh].minn=val;return;}
pushdown(wh);update(pl<=mid?lc:rc,pl,val);pushup(wh);
}
inline void change(int wh,int wl,int wr){
if(wl<=t[wh].l&&t[wh].r<=wr){pushnow(wh);return;}
pushdown(wh);if(wl<=mid)change(lc,wl,wr);if(wr>mid)change(rc,wl,wr);pushup(wh);
}
int ansum,anmin,anmax;
inline void work(int wh,int wl,int wr){
if(wl<=t[wh].l&&t[wh].r<=wr){
ansum+=t[wh].sum;anmin=min(anmin,t[wh].minn);anmax=max(anmax,t[wh].maxn);return;
}
pushdown(wh);if(wl<=mid)work(lc,wl,wr);if(wr>mid)work(rc,wl,wr);pushup(wh);
}
#undef lc
#undef rc
#undef mid
#undef num
int ev[N];
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);int s1,s2,s3;
for(int i=1;i<m;i++){
read(s1);read(s2);read(s3);
s1++,s2++;
add(s1,s2,s3);add(s2,s1,s3);
}
dfs1(1,0);dfs2(1,1);
for(int i=1;i<esum;i+=2){
int now=(i+1)>>1;
ev[now]=id[d[e[i].t]<d[e[i+1].t]?e[i+1].t:e[i].t];
fir[ev[now]]=e[i].v;
}
read(n);
build(1,1,cnt);
while(n--){
int o=op();read(s1);read(s2);
if(o==0)update(1,ev[s1],s2);
s1++;s2++;
if(o==1){
while(top[s1]^top[s2]){
if(d[top[s1]]<d[top[s2]])swap(s1,s2);
change(1,id[top[s1]],id[s1]);s1=f[top[s1]];
}
if(d[s1]>d[s2])swap(s1,s2);
if(s1^s2)change(1,id[s1]+1,id[s2]);
}
if(o>1){
ansum=0;anmax=-inf;anmin=inf;
while(top[s1]^top[s2]){
if(d[top[s1]]<d[top[s2]])swap(s1,s2);
work(1,id[top[s1]],id[s1]);s1=f[top[s1]];
}
if(d[s1]>d[s2])swap(s1,s2);
if(s1^s2)work(1,id[s1]+1,id[s2]);
if(o==2)printf("%d\n",ansum);
if(o==3)printf("%d\n",anmax);
if(o==4)printf("%d\n",anmin);
}
}
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具