Qtree1

(update)

『打错了...读入优化的时候写错了...TAT』

『另外:跑的好慢..500+名..不过在我旁边我看见了Sillycross神..ORZ..』

『3.88s...第一名0.79s...还让不当人活....』

愚昧的代码...


#include 
#include
#include
#include
#include
#include
#define max(a, b) ({int _ = (a), __ = (b); _ > __ ? _ : __;})
#define swap(a, b) ({int _ = (a); (a) = (b); (b) = _;})
#define maxn 1000005
#define fort(_, __, ___) for (int _ = (__); _ <= (___); ++_)
#define fot(_, __, ___) for (int _ = (__); _ < (___); ++_)
#define ms(a, b) memset(a, b, sizeof a)
#define termin() {puts("No solution");exit(0);}
#define openfile() freopen("qtree.in", "r", stdin); freopen("qtree.out", "w", stdout);
#define adde(a, b, c) ({*(++eptr) = (edge){b, c, h[a]}, h[a] = eptr;})

using namespace std;

struct edge
{
	int t, v;
	edge *nt;
}eg[maxn], *eptr, *h[maxn];

const int inf = ~0u>>2; char rd, order;
inline void read(int &a)
{
	a = 0; rd = getchar(); while ('0' > rd || rd > '9') rd = getchar();
	while ('0' <= rd && rd <= '9') a *= 10, a += rd - '0', rd = getchar();
}

typedef int arr[maxn];
arr length, f, ef, s, aux, to_seg, seg_rot, weight, pos, dep, q, l, r;
int n, a[maxn << 1], seg_f[maxn << 1], u, v, tot = 0, testcase, mid[maxn << 1], lt, rt;

inline int build(int s, int t)
{
	if (s == t)
	{
		a[++tot] = weight[u]; to_seg[u] = tot; u = aux[u]; return tot;
	}	
	int md = (s + t) >> 1, tmp = build(s, md);
	l[++tot] = tmp, seg_f[tmp] = tot; tmp = tot; mid[tmp] = md;
	seg_f[r[tmp] = build(md + 1, t)] = tmp;
	a[tmp] = max(a[l[tmp]], a[r[tmp]]); return tmp;
}

inline void prepare()
{
	q[1] = 1; ef[1] = 0; int head = 0, tail = 1, me;
	while (head != tail)
	{
		u = q[++head];
		if (h[u] -> t == ef[u]) h[u] = h[u] -> nt;
		for(edge *e = h[u]; e; e = e -> nt)
		{
			ef[q[++tail] = e -> t] = u; dep[q[tail]] = dep[u] + 1;
			if (e -> nt) if (e -> nt -> t == ef[u]) e -> nt = e -> nt -> nt;
		}
	}
	for(int i = n; i; --i)
	{
		s[u = q[i]] = 1; me = 0;
		for(edge *e = h[u]; e; e = e -> nt)
		{
			s[u] += s[v = e -> t];
			if (s[v] > me) aux[u] = v, me = s[v]; weight[v] = e -> v;
		}
	}
	fort(i, 1, n)
		if (!f[u = q[i]])
		{
			length[u] = -1;
			for(int j = u; j; j = aux[j]) f[j] = u, pos[j] = ++length[u];
			seg_rot[u] = build(0, length[u]);
		}
}

inline int get(int x, int s, int t)
{
	if (lt <= s && t <= rt) return a[x];
	int ret = 0;
	if (mid[x] >= lt) ret = get(l[x], s, mid[x]);
	if (mid[x] <  rt)
		{
			int ret2 = get(r[x], mid[x] + 1, t);
			if (ret < ret2) ret = ret2;
		}
	return ret;
}

inline int pathmax(int x, int y)
{
	int ret = 0, tmp; lt = 0;
	while (f[x] != f[y])
	{
		if (dep[f[x]] > dep[f[y]]) swap(x, y); rt = pos[y];
		tmp = get(seg_rot[f[y]], 0, length[f[y]]); if (ret < tmp) ret = tmp; y = ef[f[y]];
	}
	if (x != y)
	{
		if (dep[x] > dep[y]) swap(x, y);
		lt = pos[x] + 1; rt = pos[y];
		tmp = get(seg_rot[f[x]], 0, length[f[x]]); if (ret < tmp) ret = tmp;
	}
	return ret;
}

inline void put(int x, int val)
{
	int p = eg[x << 1].t, q = eg[(x << 1) - 1].t;
	if (ef[q] == p) p = q; p = to_seg[p];
	a[p] = val;
	while (seg_f[p])
		p = seg_f[p], a[p] = max(a[l[p]], a[r[p]]);
}

int main()
{
	openfile();
	read(testcase);
	while (testcase--)
	{
		read(n); eptr = eg; tot = 0; ms(h, 0); ms(seg_f, 0); ms(f, 0); ms(aux, 0);
		int a, b, c;
		fot(i, 1, n) read(a), read(b), read(c), adde(a, b, c), adde(b, a, c);
		prepare(); order = getchar(); while (order > 'Q' || order < 'C') order = getchar();
		while (order != 'D')
		{
			read(a); read(b);
			if (order == 'Q') printf("%d\n", pathmax(a, b));
			else put(a, b);
			order = getchar(); while (order > 'Q' || order < 'C') order = getchar();
		}
	}
	return 0;
}



你可能感兴趣的:(Qtree1)