题目链接:传送门
题目大意:给一棵树,三种操作,query询问 a ~ b 路径上最大边权值,change改变按输入顺序的第 a 条边的
边权为 b,negate将 a~b路径上的边权值取相反数。
题目思路:树链剖分,取相反数直接更新到底就行,不用延迟标记,若非要延迟的话,则线段树需保存最大值和
最小值。每次取反就将他俩交换并分别取反。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <algorithm> 6 #include <cstring> 7 #include <stack> 8 #include <cctype> 9 #include <queue> 10 #include <string> 11 #include <vector> 12 #include <set> 13 #include <map> 14 #include <climits> 15 #define lson rt<<1,l,mid 16 #define rson rt<<1|1,mid+1,r 17 #define fi first 18 #define se second 19 #define ping(x,y) ((x-y)*(x-y)) 20 #define mst(x,y) memset(x,y,sizeof(x)) 21 #define mcp(x,y) memcpy(x,y,sizeof(y)) 22 using namespace std; 23 #define gamma 0.5772156649015328606065120 24 #define MOD 1000000007 25 #define inf 0x3f3f3f3f 26 #define N 100005 27 #define maxn 30010 28 typedef pair<int,int> PII; 29 typedef long long LL; 30 LL read(){ 31 LL x=0,f=1;char ch=getchar(); 32 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 33 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 34 return x*f; 35 } 36 int n,m,k,sz,L,R,pre,pre2,nowr,nowl; 37 int son[N],siz[N],top[N],fa[N]; 38 int dep[N],posi[N],id[N],tid; 39 int seg[N<<2],mrk[N<<2]; 40 char str[1111]; 41 struct Edge{ 42 int x,y,v; 43 }edge[N]; 44 struct Node{ 45 int to,nxt; 46 }node[N<<1];int head[N],hcnt; 47 48 void dfs1(int u,int f,int deep){ 49 dep[u]=deep;siz[u]=1;fa[u]=f; 50 for(int i=head[u];~i;i=node[i].nxt){ 51 int e=node[i].to; 52 if(e==f)continue; 53 dfs1(e,u,deep+1); 54 siz[u]+=siz[e]; 55 if(!son[u]||siz[son[u]]<siz[e]) 56 son[u]=e; 57 } 58 } 59 void dfs2(int u,int tp){ 60 top[u]=tp,id[u]=++tid; 61 if(!son[u])return; 62 dfs2(son[u],tp); 63 for(int i=head[u];~i;i=node[i].nxt){ 64 int e=node[i].to; 65 if(id[e])continue; 66 dfs2(e,e); 67 } 68 } 69 void update(int rt,int l,int r,int v){ 70 if(l==r){ 71 if(v==inf)seg[rt]=-seg[rt]; 72 else seg[rt]=v; 73 return; 74 } 75 int mid=l+r>>1; 76 if(L<=mid)update(lson,v); 77 if(R>mid) update(rson,v); 78 seg[rt]=max(seg[rt<<1],seg[rt<<1|1]); 79 } 80 int query(int rt,int l,int r){ 81 if(L<=l&&r<=R)return seg[rt]; 82 int temp=INT_MIN,mid=l+r>>1; 83 if(L<=mid)temp=max(temp,query(lson)); 84 if(R>mid) temp=max(temp,query(rson)); 85 seg[rt]=max(seg[rt<<1],seg[rt<<1|1]); 86 return temp; 87 } 88 void init(){ 89 mst(head,-1);tid=hcnt=0; 90 mst(id,0);mst(son,0);mst(siz,0); 91 mst(mrk,0); 92 } 93 void change(int x,int y,int flag){ 94 if(!flag){ 95 L=id[edge[x].x],R=id[edge[x].x]; 96 update(1,1,n,y); 97 } 98 else{ 99 while(top[x]!=top[y]){ 100 if(dep[top[x]]<dep[top[y]])swap(x,y); 101 L=id[top[x]],R=id[x]; 102 update(1,1,n,inf); 103 x=fa[top[x]]; 104 } 105 if(dep[x]>dep[y])swap(x,y); 106 L=id[x]+1,R=id[y]; 107 update(1,1,n,inf); 108 } 109 } 110 int lca(int x,int y){ 111 int res=INT_MIN; 112 while(top[x]!=top[y]){ 113 if(dep[top[x]]<dep[top[y]])swap(x,y); 114 L=id[top[x]],R=id[x]; 115 res=max(res,query(1,1,n)); 116 x=fa[top[x]]; 117 } 118 if(dep[x]>dep[y])swap(x,y); 119 L=id[x]+1,R=id[y]; 120 if(x!=y)res=max(res,query(1,1,n)); 121 return res; 122 } 123 int main(){ 124 int i,j,group,x,y,v; 125 group=read(); 126 while(group--){ 127 init(); 128 n=read(); 129 for(i=1;i<n;++i){ 130 x=read(),y=read(),v=read(); 131 edge[i].x=x,edge[i].y=y,edge[i].v=v; 132 node[hcnt].to=y,node[hcnt].nxt=head[x],head[x]=hcnt++; 133 node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++; 134 } 135 dfs1(1,1,1);dfs2(1,1); 136 for(i=1;i<n;++i){ 137 if(dep[edge[i].x]<dep[edge[i].y])swap(edge[i].x,edge[i].y); 138 L=id[edge[i].x],R=id[edge[i].x]; 139 update(1,1,n,edge[i].v); 140 } 141 while(scanf("%s",str)!=EOF){ 142 if(str[0]=='D')break; 143 x=read(),y=read(); 144 if(str[0]=='Q') printf("%d ",lca(x,y)); 145 else if(str[0]=='C') change(x,y,0); 146 else change(x,y,1); 147 } 148 } 149 return 0; 150 }