题意是在一棵树上 的边上进行三个操作:
1.修改某条变得值
2.反转一条边的值
3.求出一条边上的max;
树上的操作+线段树
翻转的处理比较难 其他都是以前正常的线段树处理
翻转类似LAZY思想 ,然后我们设定MIN ,MAX,因为-MAX就是MIN 了,
线段树用回以前的版本了;
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 #include <queue> 8 #include <cstdlib> 9 #include <stack> 10 #include <vector> 11 #include <set> 12 #include <map> 13 using namespace std; 14 #define N 132222 15 int head[N],top[N],fa[N],tot; 16 int son[N],p[N],fp[N],dep[N],pos; 17 int sz[N]; 18 void init() 19 { 20 memset(head,-1,sizeof(head)); 21 tot=0; 22 pos=0; 23 memset(son,-1,sizeof(son)); 24 } 25 struct edge 26 { 27 int v,next; 28 }e[N<<1]; 29 void add(int u,int v) 30 { 31 e[tot].v=v; 32 e[tot].next=head[u]; 33 head[u]=tot++; 34 } 35 void dfs(int u,int f,int d) 36 { 37 dep[u]=d; 38 fa[u]=f; 39 sz[u]=1; 40 for (int i=head[u];i!=-1;i=e[i].next) 41 { 42 int v=e[i].v; 43 if (v==f) continue; 44 dfs(v,u,d+1); 45 sz[u]+=sz[v]; 46 if (son[u]==-1||sz[son[u]]<sz[v]) son[u]=v; 47 } 48 } 49 50 void getpos(int u,int sp) 51 { 52 top[u]=sp; 53 p[u]=++pos; 54 fp[pos]=u; 55 if (son[u]==-1) return; 56 getpos(son[u],sp); 57 for (int i=head[u];i!=-1;i=e[i].next) 58 { 59 int v=e[i].v; 60 if (v!=son[u]&&v!=fa[u]) 61 getpos(v,v); 62 } 63 } 64 65 66 struct node 67 { 68 int l,r,Min,Max,flag; 69 }tree[N<<2]; 70 void build(int l,int r,int rt) 71 { 72 tree[rt].l=l; 73 tree[rt].r=r; 74 tree[rt].Min=tree[rt].Max=0; 75 tree[rt].flag=0; 76 if (l==r) return; 77 int m=(l+r)>>1; 78 build(l,m,rt<<1); 79 build(m+1,r,rt<<1|1); 80 } 81 82 void pushup(int rt) 83 { 84 tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); 85 tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min); 86 } 87 88 void pushdown(int rt) 89 { 90 if (tree[rt].l==tree[rt].r) return; 91 if (tree[rt].flag) 92 { 93 tree[rt<<1].Max=-tree[rt<<1].Max; 94 tree[rt<<1].Min=-tree[rt<<1].Min; 95 swap(tree[rt<<1].Max,tree[rt<<1].Min); 96 97 tree[rt<<1|1].Max=-tree[rt<<1|1].Max; 98 tree[rt<<1|1].Min=-tree[rt<<1|1].Min; 99 swap(tree[rt<<1|1].Max,tree[rt<<1|1].Min); 100 tree[rt<<1].flag^=1; 101 tree[rt<<1|1].flag^=1; 102 tree[rt].flag=0; 103 } 104 } 105 106 void update(int p,int c,int rt) 107 { 108 if (tree[rt].l==p&&tree[rt].r==p) 109 { 110 tree[rt].Max=c; 111 tree[rt].Min=c; 112 tree[rt].flag=0; 113 return; 114 } 115 pushdown(rt); 116 int mid=(tree[rt].l+tree[rt].r)>>1; 117 if (p<=mid) update(p,c,rt<<1); 118 else update(p,c,rt<<1|1); 119 pushup(rt); 120 } 121 122 void neupdate(int l,int r,int rt) 123 { 124 if (tree[rt].l==l&&tree[rt].r==r) 125 { 126 tree[rt].Max=-tree[rt].Max; 127 tree[rt].Min=-tree[rt].Min; 128 swap(tree[rt].Max,tree[rt].Min); 129 tree[rt].flag^=1; 130 return; 131 } 132 pushdown(rt); 133 int mid=(tree[rt].l+tree[rt].r)>>1; 134 if (r<=mid) neupdate(l,r,rt<<1); 135 else if (l>mid) neupdate(l,r,rt<<1|1); 136 else 137 { 138 neupdate(l,mid,rt<<1); 139 neupdate(mid+1,r,rt<<1|1); 140 } 141 pushup(rt); 142 } 143 144 int query(int l,int r,int rt) 145 { 146 if (tree[rt].l==l&&tree[rt].r==r) return tree[rt].Max; 147 pushdown(rt); 148 int mid=(tree[rt].l+tree[rt].r)>>1; 149 if (r<=mid) return query(l,r,rt<<1); 150 else if (l>mid) return query(l,r,rt<<1|1); 151 else return max(query(l,mid,rt<<1),query(mid+1,r,rt<<1|1)); 152 pushup(rt); 153 } 154 155 int lca(int u,int v) 156 { 157 int fu=top[u],fv=top[v]; 158 int tmp=-1234567; 159 while (fu!=fv) 160 { 161 if (dep[fu]<dep[fv]) 162 { 163 swap(fu,fv); 164 swap(u,v); 165 } 166 tmp=max(tmp,query(p[fu],p[u],1)); 167 u=fa[fu]; 168 fu=top[u]; 169 } 170 if (u==v) return tmp; 171 if (dep[u]>dep[v]) swap(u,v); 172 return max(tmp,query(p[son[u]],p[v],1)); 173 } 174 175 void Negat(int u,int v) 176 { 177 int fu=top[u],fv=top[v]; 178 while (fu!=fv) 179 { 180 if (dep[fu]<dep[fv]) 181 { 182 swap(fu,fv); 183 swap(u,v); 184 } 185 neupdate(p[fu],p[u],1); 186 u=fa[fu]; 187 fu=top[u]; 188 } 189 if (u==v) return; 190 if (dep[u]>dep[v]) swap(u,v); 191 neupdate(p[son[u]],p[v],1); 192 } 193 194 int a[N][3]; 195 int main() 196 { 197 int T; 198 scanf("%d",&T); 199 while (T--) 200 { 201 int n; 202 init(); 203 scanf("%d",&n); 204 for (int i=1;i<n;i++){ 205 scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]); 206 add(a[i][0],a[i][1]); 207 add(a[i][1],a[i][0]); 208 } 209 210 dfs(1,0,0); 211 getpos(1,1); 212 build(1,pos,1); 213 for (int i=1;i<n;i++) 214 { 215 if (dep[a[i][0]]>dep[a[i][1]]) swap(a[i][0],a[i][1]); 216 update(p[a[i][1]],a[i][2],1); 217 } 218 //printf("rerEt "); 219 220 char s[10]; 221 while (scanf("%s",s)!=EOF) 222 { 223 if (s[0]=='D') break; 224 int u,v; 225 scanf("%d%d",&u,&v); 226 if (s[0]=='Q') 227 printf("%d ",lca(u,v)); 228 else if (s[0]=='N') Negat(u,v); 229 else update(p[a[u][1]],v,1); 230 } 231 } 232 return 0; 233 }