QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#751728#8547. Whose Land?000226RE 0ms16912kbC++175.3kb2024-11-15 20:19:412024-11-15 20:19:42

Judging History

你现在查看的是最新测评结果

  • [2024-11-15 20:19:42]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:16912kb
  • [2024-11-15 20:19:41]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define lep(i, l, r) for(int i = (l); i <= (r); i ++)
#define rep(i, l, r) for(int i = (l); i >= (r); i --)

const int P = 998244353;

inline int mod(int x) { return x + (x >> 31 & P);}
inline void pls(int &x, int y) { x = mod(x + y - P); }
inline void sub(int &x, int y) { x = mod(x - y); }

int power (int x, int k) {
	int res = 1;
	while (k) {
		if (k & 1) res = 1ll * res * x % P;
		x = 1ll * x * x % P; k >>= 1;
	} return res;
}

using i64 = long long;

const int N = 1e5 + 5;

int n, k, q;
vector<int> e[N];
int bfn[N], loc[N], fa[N];

struct Odt {
	struct node {
		int l;
		mutable int val;
		inline bool operator <(const node &rhs) const {
			return l < rhs.l;
		}
	} ;

	set<node> st;
	
	void clear() {
		st.clear();
		st.insert ({1, 0});
	}

	void split(int pos) {
		if (pos > n) return ;
		auto it = st.upper_bound ({pos, 0});
		-- it;
		assert (it -> l <= pos);
		if (it -> l == pos) return ;
		st.insert({pos, it -> val});
	}

	void modify (int l, int r, int v, vector<tuple<int, int, int> > & rec) {
		split (l);
		split (r + 1);
		auto itl = st.lower_bound({l, 0});
		auto itr = st.lower_bound({r + 1, 0});
		rec.clear();
		for (auto it = itl; it != itr; ++ it) {
			int r = n;
			if (next(it) != st.end())
				r = next(it) -> l - 1;
			rec.push_back ({it -> l, r, it -> val});
		}
		st.erase(itl, itr);
		st.insert({l, v});
	}
} odt;

void bfs() {
	int tot = 0;
	queue<int> q;
	q.push (1);
	while (q.size()) {
		int x = q.front(); q.pop();
		bfn[++ tot] = x;
		loc[x] = tot;
		for (int y : e[x]) if (y != fa[x]) {
			fa[y] = x;
			q.push (y);
		}
	}
}

struct bit {
	#define lowbit(x) (x & -x)
	int c[N];
	void upd(int x, int y) {
		for (; x; x -= lowbit(x)) c[x] += y;
	}
	int qry (int x) {
		int ans = 0;
		for (; x <= n; x += lowbit(x))
			ans += c[x];
		return ans;
	}
	void clear() {
		for (int i = 1; i <= n; i ++) c[i] = 0;
	}
} bt;

vector<pair<int, int> > linkqry[N];
int finalans[N * 5];

int sz[N], dfn[N];
int mnbfn[N], mxbfn[N];
int st[20][N], lg[N], dep[N];

void dfs (int x, int fx) {
	sz[x] = 1;
	dfn[x] = ++ dfn[0];
	st[0][dfn[0]] = fx;
	dep[x] = dep[fx] + 1;
	//cerr << x << " " << dep[x] << endl;
	for (int y : e[x])
		if (y != fx)
			dfs (y, x), 
			sz[x] += sz[y];
}

int updst (int x, int y) {
	return dep[x] < dep[y] ? x : y;
}

inline int lca(int x, int y) {
	if (x == y) return x;
	x = dfn[x];
	y = dfn[y];
	if (x > y) swap (x, y);
	int d = log2(y - x ++);
	return updst (st[d][x], st[d][y - (1 << d) + 1]);
}

inline int dist(int x, int y) {
	int lc = lca (x, y);
	return dep[x] + dep[y] - dep[lc] * 2;
}

void solve() {
	cin >> n >> k >> q;
	lep (i, 2, n) lg[i] = lg[i >> 1] + 1;
	lep (i, 1, n) e[i].clear(), fa[i] = 0;
	lep (i, 2, n) {
		int x, y;
		cin >> x >> y;
		e[x].push_back (y);
		e[y].push_back (x);
	}
	
	dfn[0] = 0;
	bfs ();
	dfs (1, 0);
	odt.clear();
	lep (i, 1, lg[n] + 1)
		for (int j = 1; j + (1 << i) - 1 <= n; j ++)
			st[i][j] = updst (st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);


	lep (i, 1, n) linkqry[i].clear();
	lep (i, 1, q) {
		int l, r;
		cin >> l >> r;
		linkqry[r].push_back ({l, i});
	}

	lep (i, 1, n) mnbfn[i] = n, mxbfn[i] = 1;
	lep (i, 1, n) {
		mnbfn[dep[i]] = min(mnbfn[dep[i]], bfn[i]);
		mxbfn[dep[i]] = max(mxbfn[dep[i]], bfn[i]);
	}

	bt.clear();

	auto add = [&] (int x) -> void {
		for (int nowdep = dep[x] - k; nowdep <= dep[x] + k; ++ nowdep) {
			if (nowdep <= 0) continue;

			//cerr << nowdep << endl;
			//cerr << dep[x] - k << ' ' << dep[x] + k << endl;
			//cerr << x << ' ' << dep[x] << endl;

			int L = mnbfn[nowdep];
			int R = mxbfn[nowdep];
			int find_a_node = 0;

			if (nowdep >= dep[x]) {
				auto it = lower_bound(bfn + L, bfn + R + 1, x, [&](int a, int b) {
					return dfn[a] < dfn[b];
				} );
				if (it > bfn + R) ;
				else {
					// [L, R]
					if (dist(* it, x) <= k)
						find_a_node = * it;
				}
				if (! find_a_node) {
					-- it;
					if (it >= bfn + L) {
						if (dist (*it, x) <= k)
							find_a_node = * it;
					}
				}
			} 
			else {
				int tmp = x;
				while (dep[tmp] != nowdep) 
					tmp = fa[tmp];
				find_a_node = tmp;
			}

			if (find_a_node == 0) continue;
			
			int now_id = bfn[find_a_node];
			int okl = now_id, okr = now_id;
			int l = L, r = now_id, res = now_id;
			while (l <= r) {
				int mid = (l + r) >> 1;
				if (dist(bfn[mid], x) <= k) 
					r = mid - 1, res = mid;
				else
					l = mid + 1;
			}
			okl = res;
			l = now_id, r = R, res = now_id;
			while (l <= r) {
				int mid = (l + r) >> 1;
				if (dist(bfn[mid], x) <= k) 
					l = mid + 1, res = mid;
				else
					r = mid - 1;
			}
			okr = res;

			assert (okl <= okr);

			// [okl, okr]
			vector<tuple<int, int, int> > seq;
			odt.modify(okl, okr, x, seq);
			for (auto [ll, rr, v] : seq) {
				bt.upd (v, - (rr - ll + 1) );
			}
			bt.upd (x, okr - okl + 1);
		}
	} ;

	//add (2);
	//return ;


	lep (r, 1, n) {
		add(r);
		for (auto [l, id] : linkqry[r]) {
			finalans[id] = bt.qry (l);
		}
	}

	lep (i, 1, q) cout << finalans[i] << '\n';
}

int main() {
	ios :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int Case = 1;
	cin >> Case;
	while (Case --) solve();
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 16912kb

input:

2
5 1 2
1 2
1 3
2 4
2 5
2 2
2 3
8 2 3
1 2
1 3
2 4
2 5
4 6
5 7
7 8
2 2
2 5
3 4

output:

4
5
7
8
6

result:

ok 5 number(s): "4 5 7 8 6"

Test #2:

score: -100
Runtime Error

input:

1000
500 1 500
291 2
406 9
207 13
71 15
351 17
442 18
496 19
104 20
208 23
448 34
80 42
187 44
352 45
290 46
116 47
318 50
226 52
129 55
83 59
100 60
54 61
73 65
63 66
454 67
43 71
26 74
68 26
320 75
388 76
425 79
170 81
350 83
48 85
153 86
221 90
290 95
130 96
82 98
124 82
36 99
213 100
121 101
132...

output:


result: