Submission #1308375

#TimeUsernameProblemLanguageResultExecution timeMemory
1308375minh30082008Tourism (JOI23_tourism)C++20
28 / 100
5096 ms34292 KiB
#include<bits/stdc++.h> #define fi first #define se second #define FOR(i, k, n) for(int i = k; i <= n; i++) #define FOR1(i, k, n) for(int i = k; i >= n; i--) #define pb push_back #define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) #define vi vector<int> #define pii pair<int, int> #define vii vector<pii> #define ll long long #define vll vector<ll> #define pll pair<ll, ll> #define re return 0 #define mii map<int, int> #define input "BALLOON.inp" #define output "BALLOON.out" #define rf freopen(input, "r", stdin); freopen(output, "w", stdout) using namespace std; const int maxn = 3e5 + 5; const int mod = 1e9 + 7; const int base = 998244353; const int base1 = 31; const int SZ = 320; const ll INF = 1e18; void add(int &a, int b) { a += b; if(a >= mod) a -= mod; if(a < 0) a += mod; } mt19937 rd(chrono::steady_clock::now().time_since_epoch().count()); int rand(int l, int r) { return uniform_int_distribution<int>(l, r) (rd); } int a[maxn], cnt[maxn], block[maxn], bit[maxn]; struct que{ int l, r, id; } query[maxn]; vi euler; int st[maxn], en[maxn], lg[maxn]; int depth[maxn], lca[20][maxn]; vi adj[maxn]; int N; bool cmp(que x, que y) { if(block[x.l] == block[y.l]) return x.r < y.r; return x.l < y.l; } void DFS(int u, int par) { euler.pb(u); st[u] = euler.size() - 1; for(auto v : adj[u]) { if(v == par) continue; depth[v] = depth[u] + 1; DFS(v, u); euler.pb(u); } en[u] = euler.size() - 1; } int LCA(int l, int r) { int k = lg[r - l + 1]; if(depth[lca[k][l]] < depth[lca[k][r - (1 << k) + 1]]) return lca[k][l]; return lca[k][r - (1 << k) + 1]; } int get(int u, int v) { int lca = LCA(min(st[u], st[v]), max(st[u], st[v])); return depth[u] - depth[lca] + depth[v] - depth[lca]; } int kq[maxn]; bool cmp1(int x, int y) { return st[x] < st[y]; } int get(int x) { int res = 0; while(x) { res += bit[x]; x -= x & -x; } return res; } void update(int x, int val) { while(x <= N) { bit[x] += val; x += x & -x; } } int get_id(int k) { int pos = 0, sum = 0; FOR1(i, 20, 0) { if(pos + (1 << i) <= N && sum + bit[pos + (1 << i)] < k) { pos += (1 << i); sum += bit[pos]; } } return pos + 1; } int main() { fastio; int n, m, q; cin >> n >> m >> q; FOR(i, 1, n - 1) { int u, v; cin >> u >> v; adj[u].pb(v); adj[v].pb(u); } FOR(i, 1, m) cin >> a[i]; euler.pb(0); FOR(i, 1, q) { cin >> query[i].l >> query[i].r; query[i].id = i; } FOR(i, 1, m) block[i] = (i - 1) / SZ + 1; sort(query + 1, query + 1 + q, cmp); DFS(1, 0); FOR(i, 1, (int)euler.size() - 1) lca[0][i] = euler[i]; FOR(j, 1, 19) FOR(i, 1, (int)euler.size() - (1 << j)) if(depth[lca[j - 1][i]] < depth[lca[j - 1][i + (1 << (j - 1))]]) lca[j][i] = lca[j - 1][i]; else lca[j][i] = lca[j - 1][i + (1 << (j - 1))]; FOR(i, 1, (int)euler.size()) lg[i] = __lg(i); int l = 1, r = 0; int ans = 0; N = euler.size(); FOR(i, 1, q) { while(r < query[i].r) { r++; cnt[a[r]]++; if(cnt[a[r]] > 1) continue; update(st[a[r]], 1); int cnt = get(N); if(cnt == 1) continue; int k = get(st[a[r]]); int pre = (k == 1 ? cnt : k - 1); int nex = (k == cnt ? 1 : k + 1); pre = euler[get_id(pre)]; nex = euler[get_id(nex)]; ans -= get(pre, nex); ans += get(pre, a[r]); ans += get(a[r], nex); } while(l > query[i].l) { --l; cnt[a[l]]++; if(cnt[a[l]] > 1) continue; update(st[a[l]], 1); int cnt = get(N); if(cnt == 1) continue; int k = get(st[a[l]]); int pre = (k == 1 ? cnt : k - 1); int nex = (k == cnt ? 1 : k + 1); pre = euler[get_id(pre)]; nex = euler[get_id(nex)]; ans -= get(pre, nex); ans += get(pre, a[l]); ans += get(a[l], nex); } while(r > query[i].r) { cnt[a[r]]--; if(cnt[a[r]]) { r--; continue; } int cnt = get(N); int k = get(st[a[r]]); if(cnt == 1) { update(st[a[r]], -1); r--; continue; } int pre = (k == 1 ? cnt : k - 1); int nex = (k == cnt ? 1 : k + 1); pre = euler[get_id(pre)]; nex = euler[get_id(nex)]; ans += get(pre, nex); ans -= get(pre, a[r]); ans -= get(a[r], nex); update(st[a[r]], -1); r--; } while(l < query[i].l) { cnt[a[l]]--; if(cnt[a[l]]) { l++; continue; } int cnt = get(N); int k = get(st[a[l]]); if(cnt == 1) { update(st[a[l]], -1); l++; continue; } int pre = (k == 1 ? cnt : k - 1); int nex = (k == cnt ? 1 : k + 1); pre = euler[get_id(pre)]; nex = euler[get_id(nex)]; ans += get(pre, nex); ans -= get(pre, a[l]); ans -= get(a[l], nex); update(st[a[l]], -1); l++; } kq[query[i].id] = ans / 2 + 1; } FOR(i, 1, q) cout << kq[i] << "\n"; re; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...