题目传送门
题目描述
Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。
Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。
现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。
输入输出格式
输入格式:
输入的第一行包含一个整数N,表示T 城中的景点个数。景点编号为 0...N − 1。
接下来N − 1 行,每行三个整数u、v 和w,表示有一条u 到v,使 Ray 愉悦度增加w 的桥。桥的编号为1...N − 1。|w| <= 1000。 输入的第N + 1 行包含一个整数M,表示Ray 的操作数目。
接下来有M 行,每行描述了一个操作,操作有如下五种形式:
-
C i w,表示Ray 对于经过第i 座桥的愉悦度变成了w。
-
N u v,表示Ray 对于经过景点u 到v 的路径上的每一座桥的愉悦度都变成原来的相反数。
-
SUM u v,表示询问从景点u 到v 所获得的总愉悦度。
-
MAX u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最大愉悦度。
-
MIN u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最小愉悦度。
测试数据保证,任意时刻,Ray 对于经过每一座桥的愉悦度的绝对值小于等于1000。
输出格式:
对于每一个询问(操作S、MAX 和MIN),输出答案。
输入输出样例
说明
很容易的基础题哦>.<
一道码农题=-=
节点记录该节点与父亲之间的边的边权,然后树剖+线段树即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define mid ((l+r)>>1) 7 using namespace std ; 8 const int INF = 0x7ffffff ; 9 const int N = 1e5 + 10 ; 10 11 inline int read() { 12 int k = 0 , f = 1 ; char c = getchar() ; 13 for( ; !isdigit(c) ; c = getchar()) 14 if(c == '-') f = -1 ; 15 for( ; isdigit(c) ; c = getchar()) 16 k = k*10 + c-'0' ; 17 return k*f ; 18 } 19 struct eee { 20 int x, y ; 21 }ee[N] ; 22 inline void add1(int xx,int yy) { 23 static int cnt = 0 ; 24 ee[++cnt].x = xx, ee[cnt].y = yy ; 25 } 26 27 struct Node { 28 int maxx, minn, sum, laz ; 29 Node *ls, *rs ; 30 inline void pushup() { 31 maxx = max(ls->maxx,rs->maxx) ; minn = min(ls->minn,rs->minn) ; 32 sum = ls->sum + rs->sum ; 33 } 34 inline void pushdown() { 35 if(!laz) return ; 36 ls->sum *= -1, rs->sum *= -1 ; 37 int t = ls->maxx ; 38 ls->maxx = -ls->minn, ls->minn = -t ; 39 t = rs->maxx ; 40 rs->maxx = -rs->minn, rs->minn = -t ; 41 ls->laz ^= 1 ; rs->laz ^= 1 ; laz = 0 ; 42 } 43 }pool[N<<1], *root ; int res ; int wt[N] ; 44 inline Node *newNode() { 45 static int cnt = 0 ; 46 return &pool[++cnt] ; 47 } 48 Node *build(int l,int r) { 49 Node *cur = newNode() ; cur->laz = 0 ; 50 if(l == r) { 51 cur->maxx = cur->minn = cur->sum = wt[l] ; 52 } else { 53 cur->ls = build(l,mid) ; cur->rs = build(mid+1,r) ; 54 cur->pushup() ; 55 } 56 return cur ; 57 } 58 void change_interval(Node *cur,int l,int r,int a,int b) { 59 if(l >= a && r <= b) { 60 cur->laz ^= 1 ; cur->sum *= -1 ; 61 int t = cur->maxx ; cur->maxx = -cur->minn, cur->minn = -t ; 62 return ; 63 } 64 cur->pushdown() ; 65 if(a <= mid) change_interval(cur->ls,l,mid,a,b) ; 66 if(b > mid) change_interval(cur->rs,mid+1,r,a,b) ; 67 cur->pushup() ; 68 } 69 void change_point(Node *cur,int l,int r,int k,int x) { 70 if(l == r) { 71 cur->sum = cur->maxx = cur->minn = x ; return ; 72 } 73 cur->pushdown() ; 74 if(k <= mid) change_point(cur->ls,l,mid,k,x) ; 75 else change_point(cur->rs,mid+1,r,k,x) ; 76 cur->pushup() ; 77 } 78 void get_sum(Node *cur,int l,int r,int a,int b) { 79 if(l >= a && r <= b) { 80 res += cur->sum ; return ; 81 } 82 cur->pushdown() ; 83 if(a <= mid) get_sum(cur->ls,l,mid,a,b) ; 84 if(b > mid) get_sum(cur->rs,mid+1,r,a,b) ; 85 } 86 void get_max(Node *cur,int l,int r,int a,int b) { 87 if(l >= a && r <= b) { 88 res = max(res,cur->maxx) ; return ; 89 } 90 cur->pushdown() ; 91 if(a <= mid) get_max(cur->ls,l,mid,a,b) ; 92 if(b > mid) get_max(cur->rs,mid+1,r,a,b) ; 93 } 94 void get_min(Node *cur,int l,int r,int a,int b) { 95 if(l >= a && r <= b) { 96 res = min(res,cur->minn) ; return ; 97 } 98 cur->pushdown() ; 99 if(a <= mid) get_min(cur->ls,l,mid,a,b) ; 100 if(b > mid) get_min(cur->rs,mid+1,r,a,b) ; 101 } 102 103 struct Edge { 104 int to, nex, val ; 105 }e[N<<1] ; 106 int n ; int head[N], top[N], fa[N], w[N], dep[N], siz[N], son[N], bl[N], bll[N] ; 107 inline void add_edge(int x,int y,int z) { 108 static int cnt = 0 ; 109 e[++cnt].to = y, e[cnt].nex = head[x], head[x] = cnt, e[cnt].val = z ; 110 } 111 112 void dfs1(int x,int f,int deep,int vv) { 113 w[x] = vv ; fa[x] = f ; dep[x] = deep ; siz[x] = 1 ; 114 for(int i=head[x];i;i=e[i].nex) { 115 int y = e[i].to ; if(y == f) continue ; 116 dfs1(y,x,deep+1,e[i].val) ; siz[x] += siz[y] ; 117 if(siz[y] > siz[son[x]]) son[x] = y ; 118 } 119 } 120 int cnt = 0 ; 121 void dfs2(int x,int topf) { 122 top[x] = topf ; wt[++cnt] = w[x] ; bl[x] = cnt ; 123 if(!son[x]) return ; 124 dfs2(son[x],topf) ; 125 for(int i=head[x];i;i=e[i].nex) { 126 int y = e[i].to ; if(y == fa[x] || y == son[x]) continue ; 127 dfs2(y,y) ; 128 } 129 } 130 131 inline void change1() { 132 int x = read()+1, y = read()+1 ; 133 while(top[x] != top[y]) { 134 if(dep[top[x]] < dep[top[y]]) swap(x,y) ; 135 change_interval(root,1,n,bl[top[x]],bl[x]) ; 136 x = fa[top[x]] ; 137 } 138 if(dep[x] > dep[y]) swap(x,y) ; 139 if(bl[x] < bl[y]) change_interval(root,1,n,bl[x]+1,bl[y]) ; 140 } 141 inline void query1() { 142 int x = read()+1, y = read()+1 ; res = 0 ; 143 while(top[x] != top[y]) { 144 if(dep[top[x]] < dep[top[y]]) swap(x,y) ; 145 get_sum(root,1,n,bl[top[x]],bl[x]) ; 146 x = fa[top[x]] ; 147 } 148 if(dep[x] > dep[y]) swap(x,y) ; 149 if(bl[x] < bl[y]) get_sum(root,1,n,bl[x]+1,bl[y]) ; 150 printf("%d ",res) ; 151 } 152 inline void query2() { 153 int x = read()+1, y = read()+1 ; res = -INF ; 154 while(top[x] != top[y]) { 155 if(dep[top[x]] < dep[top[y]]) swap(x,y) ; 156 get_max(root,1,n,bl[top[x]],bl[x]) ; 157 x = fa[top[x]] ; 158 } 159 if(dep[x] > dep[y]) swap(x,y) ; 160 if(bl[x] < bl[y]) get_max(root,1,n,bl[x]+1,bl[y]) ; 161 printf("%d ",res) ; 162 } 163 inline void query3() { 164 int x = read()+1, y = read()+1 ; res = INF ; 165 while(top[x] != top[y]) { 166 if(dep[top[x]] < dep[top[y]]) swap(x,y) ; 167 get_min(root,1,n,bl[top[x]],bl[x]) ; 168 x = fa[top[x]] ; 169 } 170 if(dep[x] > dep[y]) swap(x,y) ; 171 if(bl[x] < bl[y]) get_min(root,1,n,bl[x]+1,bl[y]) ; 172 printf("%d ",res) ; 173 } 174 175 int main() { 176 n = read() ; 177 for(int i=1;i<n;i++) { 178 int x = read()+1, y = read()+1, z = read() ; 179 add_edge(x,y,z) ; add_edge(y,x,z) ; 180 add1(x,y) ; 181 } 182 dfs1(1,0,1,0) ; dfs2(1,1) ; 183 root = build(1,n) ; 184 for(int i=1;i<n;i++) { 185 int xx = ee[i].x, yy = ee[i].y ; 186 bll[i] = fa[xx] == yy ? xx : yy ; 187 } 188 int m = read() ; char ss[10] ; 189 while(m--) { 190 scanf("%s",&ss) ; 191 if(ss[0] == 'C') { 192 int k = read(), x = read() ; 193 change_point(root,1,n,bl[bll[k]],x) ; 194 } else if(ss[0] == 'N') { 195 change1() ; 196 } else if(ss[0] == 'S') { 197 query1() ; 198 } else if(ss[1] == 'A') { 199 query2() ; 200 } else query3() ; 201 } 202 return 0 ; 203 }