\(\text{這題是個樹鏈剖分的板子題 (好像樹剖跑的比 LCT 快)}\)node
\(\text{這題的操做 : 區間修改 區間查詢}\)c++
\(\text{咱們考慮題目所說的沒有重複的x因此咱們不用判重直接幹}\)git
\(\text{因此把每一個加法操做即開戰存在vector裏面 而後結束了直接查詢。。}\)ui
\(\text{Yes No 是區間查詢 若是能到那個位置 就確定沒有戰爭即查詢的是0}\)spa
\(\mathcal Code\)code
//Isaunoya #include<bits/stdc++.h> using namespace std ; inline int read() { register int x = 0 ; register int f = 1 ; register char c = getchar() ; for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ; for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ; return x * f ; } int st[105] ; template < typename T > inline void write(T x , char c = '\n') { int tp = 0 ; if(x == 0) return (void) puts("0") ; if(x < 0) putchar('-') , x = -x ; for( ; x ; x /= 10) st[++ tp] = x % 10 ; for( ; tp ; tp --) putchar(st[tp] + '0') ; putchar(c) ; } //#define Online_Judge int n ; vector < pair < int , int > > v ; const int N = 3e5 + 10 ; int a[N] ; struct node { int v ; int nxt ; }; node e[N << 1] ; int head[N] ; int cnt = 0 ; inline void Add(int u , int v) { e[++ cnt].v = v ; e[cnt].nxt = head[u] ; head[u] = cnt ; return ; } int size[N] ; int top[N] , son[N] ; int fa[N] ; int id[N] ; int d[N] ; int idx = 0 ; inline void Dfs1(int u) { size[u] = 1 ; for(register int i = head[u] ; i ; i = e[i].nxt) { int v = e[i].v ; if(v ^ fa[u]) { fa[v] = u ; d[v] = d[u] + 1 ; Dfs1(v) ; size[u] += size[v] ; if(size[son[u]] < size[v]) son[u] = v ; } } } inline void Dfs2(int u , int t) { id[u] = ++ idx ; top[u] = t ; a[idx] = 0 ; if(! son[u]) return ; Dfs2(son[u] , t) ; for(register int i = head[u] ; i ; i = e[i].nxt) { int v = e[i].v ; if(v ^ fa[u] && v ^ son[u]) { Dfs2(v , v) ; } } } int sum[N << 2] ; int tag[N << 2] ; inline void build(int l , int r , int rt) { if(l == r) { sum[rt] = a[l] ; tag[rt] = 0 ; return ; } int mid = l + r >> 1 ; build(l , mid , rt << 1) ; build(mid + 1 , r , rt << 1 | 1) ; sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ; return ; } inline void Push_down(int rt , int l , int r) { if(tag[rt]) { tag[rt << 1] += tag[rt] ; tag[rt << 1 | 1] += tag[rt] ; int mid = l + r >> 1 ; sum[rt << 1] += tag[rt] * (mid - l + 1) ; sum[rt << 1 | 1] += tag[rt] * (r - mid) ; tag[rt] = 0 ; return ; } } inline void Change(int a , int b , int l , int r , int rt , int val) { if(a <= l && r <= b) { sum[rt] += val * (r - l + 1) ; tag[rt] += val ; return ; } int mid = l + r >> 1 ; Push_down(rt , l , r) ; if(a <= mid) Change(a , b , l , mid , rt << 1 , val) ; if(b > mid) Change(a , b , mid + 1 , r , rt << 1 | 1 , val) ; sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ; return ; } inline int Query(int a , int b , int l , int r , int rt) { if(a <= l && r <= b) return sum[rt] ; int mid = l + r >> 1 ; int ans = 0 ; Push_down(rt , l , r) ; if(a <= mid) ans += Query(a , b , l , mid , rt << 1) ; if(b > mid) ans += Query(a , b , mid + 1 , r , rt << 1 | 1) ; return ans ; } inline int Query_Range(int x , int y) { int fx = top[x] ; int fy = top[y] ; int ans = 0 ; while(fx ^ fy) { if(d[fx] < d[fy]) swap(x , y) , swap(fx , fy) ; ans += Query(id[fx] , id[x] , 1 , n , 1) ; x = fa[fx] ; fx = top[x] ; } if(id[x] > id[y]) swap(x , y) ; ans += Query(id[x] + 1 , id[y] , 1 , n , 1) ; return ans ; } inline void Change_Range(int x , int y , int val) { int fx = top[x] ; int fy = top[y] ; int ans = 0 ; while(fx ^ fy) { if(d[fx] < d[fy]) swap(x , y) , swap(fx , fy) ; Change(id[fx] , id[x] , 1 , n , 1 , val) ; x = fa[fx] ; fx = top[x] ; } if(id[x] > id[y]) swap(x , y) ; Change(id[x] + 1 , id[y] , 1 , n , 1 , val) ; } signed main() { #ifdef Online_Judge freopen("testdata.in" , "r" , stdin) ; freopen("testdata2.out" , "w" , stdout) ; #endif n = read() ; int q = read() ; for(register int i = 1 ; i <= n - 1 ; i ++) { int u = read() ; int v = read() ; Add(u , v) ; Add(v , u) ; } Dfs1(1) ; Dfs2(1 , 1) ; build(1 , n , 1) ; for(register int i = 1 ; i <= q ; i ++) { register char c = getchar() ; for( ; c != 'C' && c != 'Q' && c != 'U' ; c = getchar()) ; if(c == 'Q') { int x = read() , y = read() ; if(Query_Range(x , y)) puts("No") ; else puts("Yes") ; } if(c == 'C') { int x = read() , y = read() ; Change_Range(x , y , 1) ; v.push_back(make_pair(x , y)) ; } if(c == 'U') { int num = read() - 1 ; int x = v[num].first ; int y = v[num].second ; Change_Range(x , y , - 1) ; } } return 0 ; }