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 }

浙公网安备 33010602011771号