为什么总是 TLE
查看原帖
为什么总是 TLE
148851
wtyqwq楼主2020/7/1 09:59

树上莫队,本地极限数据 1825 ms1825\ \text{ms} 通过,交上去 TLE\text{TLE}.

LCA\text{LCA} 是用树链剖分求的,曾经过了 P3379

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <algorithm>
#define R register
#define N 40005
#define M 100005
using namespace std;
char Buf[1 << 24], *S(Buf), *T(Buf);
#define getchar() (S == T && (T = (S = Buf) + fread(Buf, 1, 1 << 24, stdin), S == T) ? EOF : *S++)
inline int input() {
    R int x(0), f(0);
    R char c(getchar());
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? -x : x;
}
int Ans, his[N << 2], Sta[N], End[N], ans[M], n, m, dfn, len, cnt, a[N], buc[N];
struct Query {
	int l, r, pos, lca;
	inline Query(int _L = 0, int _R = 0, int _Pos = 0, int _LCA = 0) : l(_L), r(_R), pos(_Pos), lca(_LCA) {}
	inline bool operator < (const Query &b) {
		int Pos(l / len);
		if (Pos != b.l / len)
			return Pos < b.l / len;
		return Pos & 1 ? r < b.r : r > b.r;
	}
};
Query Q[M];
int head[N], ver[N << 1], nex[N << 1], tot;
int size[N], deep[N], fa[N], son[N], top[N];
bool vis[N];
inline void add(int x, int y) {
	ver[++tot] = y, nex[tot] = head[x], head[x] = tot;
}
void Dfs1(int x, int f) {
	his[++dfn] = x, Sta[x] = dfn;
    fa[x] = f, size[x] = 1, deep[x] = deep[f] + 1;
    for (int i(head[x]), y; i; i = nex[i]) {
        if ((y = ver[i]) == f)
            continue;
        Dfs1(y, x), size[x] += size[y];
        if (size[y] > size[son[x]])
            son[x] = y;
    }
    his[++dfn] = x, End[x] = dfn;
}
void Dfs2(int x, int f) {
    if (son[x])
        top[son[x]] = x, Dfs2(son[x], x);
    for (int i(head[x]), y; i; i = nex[i])
        if (!top[y = ver[i]])
            top[y] = y, Dfs2(y, x);
}
inline void swap(int &a, int &b) {
	int t(a);
	a = b, b = t;
}
inline int LCA(int x, int y) {
    R int tx(top[x]), ty(top[y]);
    while (tx != ty) {
        if (deep[tx] < deep[ty])
            swap(x, y), swap(tx, ty);
        x = fa[x], tx = top[x];
    }
    if (deep[x] > deep[y])
        swap(x, y);
    return x;
}
struct Data {
	int pos, val;
	inline Data(int Pos = 0, int Val = 0) : pos(Pos), val(Val) {}
	inline bool operator < (const Data &b) { return val < b.val; }
};
Data d[N];
inline void DEL(int x) { Ans -= (--buc[x] == 0); }
inline void ADD(int x) { Ans += (++buc[x] == 1); }
inline void Add(int x) {
	vis[x] ? DEL(a[x]) : ADD(a[x]), vis[x] ^= true;
}
int main() {
	len = sqrt(n = input()), m = input();
	for (int i(1); i <= n; ++i) d[i] = Data(i, input());
	sort(d + 1, d + n + 1);
	for (int i(1); i <= n; ++i)
		if (i == 1 || d[i].val != d[i - 1].val)
			a[d[i].pos] = ++cnt;
		else
			a[d[i].pos] = cnt;
	for (int i(1); i < n; ++i) {
		int x(input()), y(input());
		add(x, y), add(y, x);
	}
	Dfs1(1, 0), top[1] = 1, Dfs2(1, 0);
	for (int i(1); i <= m; ++i) {
		int x(input()), y(input());
		if (Sta[x] > Sta[y])
			swap(x, y);
		int lca = LCA(x, y);
		if (lca == x)
			Q[i] = Query(Sta[x], Sta[y], i);
		else
			Q[i] = Query(End[x], Sta[y], i, lca);
	}
	sort(Q + 1, Q + m + 1);
	int l = 1, r = 0;
	for (int i(1); i <= m; ++i) {
		while (l < Q[i].l) Add(his[l]), ++l;
		while (l > Q[i].l) Add(his[--l]);
		while (r < Q[i].r) Add(his[++r]);
		while (r > Q[i].r) Add(his[r]), --r;
		if (Q[i].lca)
			Add(Q[i].lca);
		ans[Q[i].pos] = Ans;
		if (Q[i].lca)
			Add(Q[i].lca);
	}
	for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
    return 0; 
}
2020/7/1 09:59
加载中...