QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#869586 | #9221. Missing Boundaries | xcs321 | WA | 10ms | 75056kb | C++14 | 4.8kb | 2025-01-25 11:38:25 | 2025-01-25 11:38:26 |
Judging History
answer
#include<bits/stdc++.h>
#define N 1000005
#define M 20000007
using namespace std;
int n, m, B, root;
vector<int>p[N];
int dep[N], ans[N], dfn[N], len, tot, n1, n2;
struct RMQ_LCA { //O(n log n) - O(1) LCA
int z[N], r[N], lg[N], tot;
int f[100005][22];
void dfs(int x, int fa) {
dep[x] = dep[fa] + 1;
r[++tot] = x;
dfn[x] = ++len;
z[x] = tot;
for(auto y : p[x]) {
dfs(y, x);
r[++tot] = x;
}
}
int Min(int x, int y) {
return dep[x] < dep[y] ? x : y;
}
int LCA(int x, int y) {
x = z[x], y = z[y];
if(x > y) swap(x, y);
int h = lg[y - x + 1];
return Min(f[x][h], f[y - (1 << h) + 1][h]);
}
void init() {
dfs(root, 0);
for(int i = 2; i <= tot; i++) lg[i] = lg[i / 2] + 1;
for(int i = 1; i <= tot; i++) f[i][0] = r[i];
for(int j = 1; j <= 20; j++)
for(int i = 1; i + (1 << j) - 1 <= tot; i++) f[i][j] = Min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
}ljm;
int tim1, tim2;
struct DS { //分块:O(1)修改, O(sqrt(n))查询
int v1[N], v2[N];
int X[M], Y[M];
int Get(int x) {
return ceil((double)x * 1.0 / B);
}
void update(int x, int y) {
X[++tim1] = x; Y[tim1] = y;
v1[Get(x)] += y;
v2[x] += y;
}
int query(int L, int R) {
int res = 0;
for(int i = L; i <= R; ) {
if(i % B == 1 && i + B - 1 <= R) res += v1[Get(i)], i += B;
else res += v2[i], i++;
}
return res;
}
void Go(int x) { //撤销回到时间轴为x时
while(tim1 > x) {
v1[Get(X[tim1])] -= Y[tim1];
v2[X[tim1]] -= Y[tim1];
tim1--;
}
}
}ds;
struct List {
int Pre, Nxt;
}t[N];
struct node {
int l, r, x, id;
}z[N], h[N];
bool cmp1(node A, node B) {
return A.l < B.l;
}
bool cmp2(node A, node B) {
return A.r > B.r;
}
int v[N];
bool cmp(int x, int y) {
return dfn[x] < dfn[y];
}
vector<int>r[N];
void Prepare() {
for(int i = 1; i <= n; i++) v[i] = i;
sort(v + 1, v + n + 1, cmp);
for(int i = 1; i <= n; i++) r[dep[v[i]]].push_back(v[i]);
for(int d = 1; d <= n; d++) {
for(int i = 0; i < r[d].size(); i++) {
if(i == 0) t[r[d][i]].Pre = -1;
else t[r[d][i]].Pre = r[d][i - 1];
if(i == r[d].size() - 1) t[r[d][i]].Nxt = -1;
else {
t[r[d][i]].Nxt = r[d][i + 1];
ds.update(d - dep[ljm.LCA(r[d][i], r[d][i + 1])], 1);
}
}
if(r[d].size()) ds.update(d, 1); //d深度只要有一个,贡献就要加1
}
n1 = tim1, n2 = tim2;
}
int X[M], Y[M], opt[M];
void Go(int x) {
while(tim2 > x) {
if(opt[tim2] == 1) t[X[tim2]].Pre = Y[tim2];
else t[X[tim2]].Nxt = Y[tim2];
tim2--;
}
}
void Del(int x) {
if(t[x].Pre != -1) {
ds.update(dep[x] - dep[ljm.LCA(x, t[x].Pre)], -1);
tim2++; X[tim2] = t[x].Pre, Y[tim2] = t[t[x].Pre].Nxt, opt[tim2] = 2;
t[t[x].Pre].Nxt = t[x].Nxt;
}
if(t[x].Nxt != -1) {
ds.update(dep[x] - dep[ljm.LCA(x, t[x].Nxt)], -1);
tim2++; X[tim2] = t[x].Nxt, Y[tim2] = t[t[x].Nxt].Pre, opt[tim2] = 1;
t[t[x].Nxt].Pre = t[x].Pre;
}
if(t[x].Pre != -1 && t[x].Nxt != -1)
ds.update(dep[x] - dep[ljm.LCA(t[x].Pre, t[x].Nxt)], 1);
if(t[x].Pre == -1 && t[x].Nxt == -1) //这个深度删掉没有点了
ds.update(dep[x], -1);
}
void Sol(int L, int R) { //处理左端点在[L,R]的询问
sort(h + 1, h + tot + 1, cmp2);
for(int i = 1; i < L; i++) Del(i);
int curL = L, curR = n;
for(int i = 1; i <= tot; i++) {
while(curR > h[i].r) Del(curR--);
int lst1 = tim1, lst2 = tim2;
while(curL < h[i].l) Del(curL++);
ans[h[i].id] = ds.query(h[i].x + 1, n)+(ds.query(h[i].x, n)-ds.query(h[i].x + 1, n) != 0);
ds.Go(lst1); Go(lst2);
curL = L;
}
ds.Go(n1); Go(n2);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m; B = sqrt(n);
for(int i = 1, fa; i <= n; i++) {
cin >> fa;
if(fa) p[fa].push_back(i);
else root = i;
}
ljm.init(); Prepare();
for(int i = 1; i <= m; i++) cin >> z[i].l >> z[i].r >> z[i].x, z[i].id = i;
sort(z + 1, z + m + 1, cmp1);
int j = 0;
for(int i = 1; i <= n; i += B) {
tot = 0;
while(j + 1 <= m && z[j + 1].l <= i + B - 1) j++, h[++tot] = z[j];
Sol(i, min(n, i + B - 1));
}
for(int i = 1; i <= m; i++) cout << ans[i] << endl;
return 0;
}
/*
7 1
0 1 1 1 3 1 4
1 7 1
*/
/*
10 1
0 1 1 1 3 1 4 3 2 3
1 7 1
*/
//start : 2025/1/24 19:03
詳細信息
Test #1:
score: 0
Wrong Answer
time: 10ms
memory: 75056kb
input:
3 4 51 1 -1 11 50 -1 -1 -1 10 3 2 -1 -1 -1 -1 -1 -1 2 3 1 2 2 3
output:
0 0 1 0
result:
wrong answer 1st lines differ - expected: 'TAK', found: '0'