20150205~07
20150208 WC2015 Day-1

HDU5173 GTY's game II

laekov posted @ 2015年2月07日 23:10 in 未分类 with tags hdu bc ds , 810 阅读

bc的题。今天bc又挂了。这题没有写完,然后b题fst了。伤心啊。

 

其实思路比较简单。直接链剖dfs序上把所有区间找出来swap就好了。不过代码实现起来还是比较麻烦的,很容易绕晕。加上smt久了没写手生了,于是就调了一晚上。唉,我还是太年轻了。

 

1	#include <cstdio>
2	#include <cstdlib>
3	#include <cstring>
4	#include <algorithm>
5	
6	using namespace std;
7	
8	struct node {
9		int v, s, sz, w, rv;
10		node *ls, *rs;
11		inline void update() {
12			sz = 1;
13			s = v;
14			if (ls) {
15				sz += ls-> sz;
16				s += ls-> s;
17			}
18			if (rs) {
19				sz += rs-> sz;
20				s += rs-> s;
21			}
22		}
23		inline void fix() {
24			if (rv) {
25				swap(ls, rs);
26				if (ls)
27					ls-> rv ^= 1;
28				if (rs)
29					rs-> rv ^= 1;
30				rv = 0;
31			}
32		}
33	};
34	typedef pair <node*, node*> npr;
35	
36	const int maxn = 80009;
37	
38	#define szof(p) ((p)?(p->sz):0)
39	#define sof(p) ((p)?(p->s):0)
40	node nlst[maxn << 1], *np(nlst);
41	node* newNode(int v) {
42		np-> ls = np-> rs = 0;
43		np-> v = np-> s = v;
44		np-> sz = 1;
45		np-> rv = 0;
46	#ifdef WIN32
47		np-> w = (rand() << 16) | rand();
48	#else
49		np-> w = rand();
50	#endif
51		return np ++;
52	}
53	node* merge(node* p, node* q) {
54		if (p)
55			p-> fix();
56		else
57			return q;
58		if (q)
59			q-> fix();
60		else
61			return p;
62		if (p-> w > q-> w) {
63			p-> rs = merge(p-> rs, q);
64			p-> update();
65			return p;
66		}
67		else {
68			q-> ls = merge(p, q-> ls);
69			q-> update();
70			return q;
71		}
72	}
73	npr split(node* p, int k) {
74		if (!k)
75			return npr(0, p);
76		else if (!p || p-> sz == k)
77			return npr(p, 0);
78		else {
79			p-> fix();
80			if (k <= szof(p-> ls)) {
81				npr g(split(p-> ls, k));
82				p-> ls = g. second;
83				p-> update();
84				return npr(g. first, p);
85			}
86			else {
87				npr g(split(p-> rs, k - szof(p-> ls) - 1));
88				p-> rs = g. first;
89				p-> update();
90				return npr(p, g. second);
91			}
92		}
93	}
94	int smtQry(node* p, int k) {
95		int s(0);
96		while (p && k) {
97			p-> fix();
98			if (k <= szof(p-> ls))
99				p = p-> ls;
100			else
101				s += sof(p-> ls) + p-> v, k -= szof(p-> ls) + 1, p = p-> rs;
102		}
103		return s;
104	}
105	
106	struct edge {
107		int t;
108		edge *next;
109	};
110	edge *head[maxn], elst[maxn << 1], *ep(elst);
111	inline void addEdge(int u, int v) {
112		ep-> t = v;
113		ep-> next = head[u];
114		head[u] = ep ++;
115	}
116	
117	int v[maxn], n, m;
118	int tc, fa[maxn], d[maxn], sz[maxn], fs[maxn], fc[maxn], ch[maxn];
119	int dfb[maxn], dfo[maxn];
120	node *rt, *remp;
121	
122	void divide() {
123		static int stc[maxn];
124		int tst(1), dfn(0);
125		memset(fa, 0, sizeof(fa));
126		stc[tst] = 1;
127		while (tst) {
128			int p(stc[tst --]);
129			dfo[++ dfn] = p;
130			for (edge* e = head[p]; e; e = e-> next)
131				if (e-> t ^ fa[p]) {
132					fa[e-> t] = p;
133					d[e-> t] = d[p] + 1;
134					stc[++ tst] = e-> t;
135				}
136		}
137		tc = 0;
138		for (int i = n; i; -- i) {
139			int p(dfo[i]);
140			fs[p] = -1;
141			sz[p] = 1;
142			for (edge* e = head[p]; e; e = e-> next)
143				if (fa[e-> t] == p) {
144					sz[p] += sz[e-> t];
145					if (fs[p] == -1 || sz[e-> t] > sz[fs[p]])
146						fs[p] = e-> t;
147				}
148			if (fs[p] == -1)
149				fc[p] = ++ tc;
150			else
151				fc[p] = fc[fs[p]];
152			ch[fc[p]] = p;
153		}
154		stc[tst = 1] = 1;
155		dfn = 0;
156		while (tst) {
157			int p(stc[tst --]);
158			dfo[++ dfn] = p;
159			dfb[p] = dfn;
160			for (edge* e = head[p]; e; e = e-> next)
161				if (fa[e-> t] == p && e-> t != fs[p])
162					stc[++ tst] = e-> t;
163			if (fs[p] != -1)
164				stc[++ tst] = fs[p];
165		}
166		rt = 0;
167		for (int i = 1; i <= n; ++ i)
168			rt = merge(rt, newNode(v[dfo[i]]));
169		remp = 0;
170		for (int i = 1; i <= n; ++ i)
171			remp = merge(remp, newNode(-1));
172	}
173	
174	int query(int u, int v) {
175		int s(0);
176		while (fc[u] ^ fc[v])
177			if (d[ch[fc[u]]] > d[ch[fc[v]]]) {
178				s += smtQry(rt, dfb[u]) - smtQry(rt, dfb[ch[fc[u]]] - 1);
179				u = fa[ch[fc[u]]];
180			}
181			else {
182				s += smtQry(rt, dfb[v]) - smtQry(rt, dfb[ch[fc[v]]] - 1);
183				v = fa[ch[fc[v]]];
184			}
185		if (d[u] < d[v])
186			s += smtQry(rt, dfb[v]) - smtQry(rt, dfb[u] - 1);
187		else
188			s += smtQry(rt, dfb[u]) - smtQry(rt, dfb[v] - 1);
189		return s;
190	}
191	
192	bool checkTree(node* p, char e) {
193		if (p) {
194			if (p-> rv) {
195				checkTree(p-> rs, 32);
196				printf("%d%c", p-> v, e);
197				checkTree(p-> ls, 32);
198			}
199			else {
200				checkTree(p-> ls, 32);
201				printf("%d%c", p-> v, e);
202				checkTree(p-> rs, 32);
203			}
204		}
205		return 0;
206	}
207	
208	typedef pair <int, int> rpr;
209	rpr ra[maxn], rb[maxn];
210	void flip(int u, int v) {
211		int tra(0), trb(0);
212		while (fc[u] ^ fc[v]) {
213			if (d[ch[fc[u]]] > d[ch[fc[v]]]) {
214				ra[tra ++] = rpr(dfb[ch[fc[u]]], dfb[u]);
215				u = fa[ch[fc[u]]];
216			}
217			else {
218				rb[trb ++] = rpr(dfb[ch[fc[v]]], dfb[v]);
219				v = fa[ch[fc[v]]];
220			}
221		}
222		if (d[u] < d[v])
223			rb[trb ++] = rpr(dfb[u], dfb[v]);
224		else
225			ra[tra ++] = rpr(dfb[v], dfb[u]);
226		node *cr(0);
227		for (int i = 0; i < tra; ++ i) {
228			npr x = split(rt, ra[i]. first - 1);
229			npr y = split(x. second, ra[i]. second - ra[i]. first + 1);
230			cr = merge(y. first, cr);
231			npr z = split(remp, ra[i]. second - ra[i]. first + 1);
232			remp = z. second;
233			x. second = merge(z. first, y. second);
234			rt = merge(x. first, x. second);
235		}
236		if (cr)
237			cr-> rv ^= 1;
238		for (int i = trb - 1; i >= 0; -- i) {
239			npr x = split(rt, rb[i]. first - 1);
240			npr y = split(x. second, rb[i]. second - rb[i]. first + 1);
241			cr = merge(cr, y. first);
242			npr z = split(remp, rb[i]. second - rb[i]. first + 1);
243			remp = z. second;
244			x. second = merge(z. first, y. second);
245			rt = merge(x. first, x. second);
246		}
247		if (cr)
248			cr-> rv ^= 1;
249		for (int i = 0; i < tra; ++ i) {
250			npr x = split(rt, ra[i]. first - 1);
251			npr y = split(x. second, ra[i]. second - ra[i]. first + 1);
252			npr z = split(cr, ra[i]. second - ra[i]. first + 1);
253			cr = z. second;
254			if (z. first)
255				z. first-> rv ^= 1;
256			x. second = merge(z. first, y. second);
257			rt = merge(x. first, x. second);
258			remp = merge(remp, y. first);
259		}
260		if (cr)
261			cr-> rv ^= 1;
262		for (int i = 0; i < trb; ++ i) {
263			npr x = split(rt, rb[i]. first - 1);
264			npr y = split(x. second, rb[i]. second - rb[i]. first + 1);
265			npr z = split(cr, rb[i]. second - rb[i]. first + 1);
266			cr = z. second;
267			if (z. first)
268				z. first-> rv ^= 1;
269			x. second = merge(z. first, y. second);
270			rt = merge(x. first, x. second);
271			remp = merge(remp, y. first);
272		}
273	}
274	
275	int main() {
276	#ifndef ONLINE_JUDGE
277		freopen("in.txt", "r", stdin);
278	#endif
279	
280		memset(head, 0, sizeof(head));
281		scanf("%d%d", &n, &m);
282		for (int i = 1; i <= n; ++ i)
283			scanf("%d", v + i);
284		for (int i = 1; i < n; ++ i) {
285			int u, v;
286			scanf("%d%d", &u, &v);
287			addEdge(u, v);
288			addEdge(v, u);
289		}
290		divide();
291		while (m --) {
292			int opt, u, v;
293			scanf("%d%d%d", &opt, &u, &v);
294			if (opt == 0)
295				printf("%d\n", query(u, v));
296			else
297				flip(u, v);
298		}
299	}
300	

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter