找出dfs序。。。成段更新维护线段树就好了。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 100005 #define maxm 100005 #define eps 1e-10 #define mod 10000007 #define INF 1e9 #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} void scanf(int &__x){__x=0;char __ch=getchar();while(__ch==' '||__ch=='\n')__ch=getchar();while(__ch>='0'&&__ch<='9')__x=__x*10+__ch-'0',__ch = getchar();} LL gcd(LL _a, LL _b){if(!_b) return _a;else return gcd(_b, _a%_b);} //head char str[maxn]; string s; map<string, int> mpp; int h[maxn], next[maxm], v[maxm], cost[maxm], vis[maxn]; int in[maxn], out[maxn], road[maxn], p[maxn], t[maxm]; int cnt, n, dfs_clock, ql, qr, m; int sum[maxn<<2][2], mark[maxn<<2]; void addedges(int a, int b, int c, int id) { next[cnt] = h[a], h[a] = cnt, v[cnt] = b, cost[cnt] = c, t[cnt] = id, cnt++; } void init(void) { cnt = dfs_clock = 0; mpp.clear(); memset(h, -1, sizeof h); memset(p, 0, sizeof p); memset(vis, 0, sizeof vis); } void read(void) { int a, b, c; scanf("%d", &n); for(int i = 1; i <= n; i++) cin >> s, mpp[s] = i; for(int i = 1; i < n; i++) { cin >> s, a = mpp[s]; cin >> s, b = mpp[s]; scanf("%d", &c); addedges(a, b, c, i); addedges(b, a, c, i); } scanf("%d", &m); } void dfs(int u) { ++dfs_clock; in[u] = dfs_clock; for(int e = h[u]; ~e; e = next[e]) if(!vis[v[e]]) road[t[e]] = v[e], vis[v[e]] = 1, p[v[e]] = cost[e], dfs(v[e]); out[u] = dfs_clock; } void build(int o, int L, int R) { sum[o][0] = R - L + 1, sum[o][1] = mark[o] = 0; if(L == R) return; int mid = (L + R) >> 1; build(lson); build(rson); } void pushdown(int o) { if(!mark[o]) return; swap(sum[ls][0], sum[ls][1]); swap(sum[rs][0], sum[rs][1]); mark[ls] ^= mark[o]; mark[rs] ^= mark[o]; mark[o] = 0; } void pushup(int o) { sum[o][0] = sum[ls][0] + sum[rs][0]; sum[o][1] = sum[ls][1] + sum[rs][1]; } void updata(int o, int L, int R) { if(ql <= L && qr >= R) { swap(sum[o][0], sum[o][1]); mark[o] ^= 1; return; } pushdown(o); int mid = (L + R) >> 1; if(ql <= mid) updata(lson); if(qr > mid) updata(rson); pushup(o); } void work(void) { int a, b, k; LL ans; vis[1] = 1; dfs(1); build(1, 1, dfs_clock); for(int i = 1; i <= n; i++) if(p[i]) { ql = in[i], qr = out[i]; updata(1, 1, dfs_clock); } while(m--) { scanf("%s", str); if(str[0] == 'Q') { a = sum[1][0]; b = sum[1][1]; ans = (LL)a * b * 2; printf("%I64d\n", ans); } else { scanf("%d", &k); ql = in[road[k]], qr = out[road[k]]; updata(1, 1, dfs_clock); } } } int main(void) { int _, __; while(scanf("%d", &_)!=EOF) { __ = 0; while(_--) { init(); read(); printf("Case #%d:\n", ++__); work(); } } return 0; }