Hdu--5039(线段树,Dfs序列)

2014-10-03 02:22:29

思路:一道线段树+DFS序列的好题,考察很全面,题解很多不赘述了,训练了DFS序列以及把边转化为点的思想。(用cin没关同步会TLE)

  1 /*************************************************************************
  2     > File Name: 5039.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com
  5     > Created Time: Thu 02 Oct 2014 10:50:41 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <queue>
 14 #include <string>
 15 #include <map>
 16 #include <iostream>
 17 #include <algorithm>
 18 using namespace std;
 19 #define lp (p << 1)
 20 #define rp (p << 1|1)
 21 #define getmid(l,r) (l + (r - l) / 2)
 22 typedef long long ll;
 23 const int INF = 1 << 30;
 24 const int maxn = 60010;
 25 
 26 int T,N,M;
 27 int sta[maxn],t1[maxn],t2[maxn],tot,stval[maxn];
 28 int first[maxn],next[maxn],ver[maxn],ecnt;
 29 map<string,int> mp;
 30 string name,s1,s2;
 31 pair<int,int> e[maxn];
 32 
 33 struct node{
 34     int sum,cover;
 35 }t[maxn << 2];
 36 
 37 void Add(int u,int v,int x){
 38     next[++ecnt] = first[u];
 39     first[u] = ecnt;
 40     ver[ecnt] = v;
 41     sta[ecnt] = x;
 42 }
 43 
 44 void Dfs(int p,int pre,int val){
 45     t1[p] = ++tot;
 46     stval[tot] = val;
 47     for(int i = first[p]; i; i = next[i])
 48         if(ver[i] != pre) Dfs(ver[i],p,val ^ sta[i]);
 49     t2[p] = tot;
 50 }
 51 
 52 void Push_up(int p){
 53     t[p].sum = t[lp].sum + t[rp].sum;
 54 }
 55 
 56 void Build_tree(int p,int l,int r){
 57     t[p].cover = 0;
 58     if(l == r){
 59         t[p].sum = stval[l];
 60         return;
 61     }
 62     int mid = getmid(l,r);
 63     Build_tree(lp,l,mid);
 64     Build_tree(rp,mid + 1,r);
 65     Push_up(p);
 66 }
 67 
 68 void Push_down(int p,int l,int mid,int r){
 69     if(t[p].cover){
 70         t[lp].cover ^= 1;
 71         t[lp].sum = mid - l + 1 - t[lp].sum;
 72         t[rp].cover ^= 1;
 73         t[rp].sum = r - mid - t[rp].sum;
 74         t[p].cover = 0;
 75     }
 76 }
 77 
 78 void Update_tree(int a,int b,int p,int l,int r){
 79     if(a <= l && r <= b){
 80         t[p].cover ^= 1;
 81         t[p].sum = r - l + 1 - t[p].sum;
 82         return;
 83     }
 84     int mid = getmid(l,r);
 85     Push_down(p,l,mid,r);
 86     if(a <= mid) Update_tree(a,b,lp,l,mid);
 87     if(b > mid) Update_tree(a,b,rp,mid + 1,r);
 88     Push_up(p);
 89 }
 90 
 91 void Init(){
 92     memset(first,0,sizeof(first));
 93     ecnt = tot = 0;
 94 }
 95 
 96 int main(){
 97     ios::sync_with_stdio(false);
 98     char s[5];
 99     int x,id1,id2;
100     cin >> T;
101     for(int Case = 1; Case <= T; ++Case){
102         Init();
103         cin >> N;
104         for(int i = 1; i <= N; ++i){
105             cin >> name;
106             mp[name] = i;
107         }
108         for(int i = 1; i < N; ++i){
109             cin >> s1 >> s2 >> x;
110             id1 = mp[s1];
111             id2 = mp[s2];
112             Add(id1,id2,x);
113             Add(id2,id1,x);
114             e[i] = make_pair(id1,id2);
115         }
116         Dfs(1,0,0);
117         Build_tree(1,1,N);
118         printf("Case #%d:\n",Case);
119         cin >> M;
120         for(int i = 1; i <= M; ++i){
121             cin >> s;
122             if(s[0] == 'Q'){
123                 int tmp = t[1].sum;
124                 printf("%d\n",tmp * (N - tmp) * 2);
125             }
126             else{
127                 cin >> x;
128                 int u = e[x].first;
129                 int v = e[x].second;
130                 if(t1[u] < t1[v]) u = v;
131                 Update_tree(t1[u],t2[u],1,1,N);
132             }
133         }
134     }
135     return 0;
136 }

 

posted @ 2014-10-03 02:23  Naturain  阅读(218)  评论(0)    收藏  举报