光输出就用了1000ms,直接就TLE了...
题目链接(NKOJ上只有1s...)
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
const int N = 2e5 + 10, M = 25010, K = sqrt(N) + 10;
int n, r, q, k, a[N];
vector<int> r1[M], r2[M], big;
int len[M], to[N];
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline char gc()
{
if(p1 == p2)
p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin);
return p1 == p2 ? EOF : *(p1++);
}
inline int read()
{
int f = 1, w = 0;
char ch = gc();
while(ch < '0' || '9' < ch)
{
if(ch == '-') f = -1;
ch = gc();
}
while('0' <= ch && ch <= '9')
{
w = (w << 1) + (w << 3) + (ch ^ 48);
ch = gc();
}
return f * w;
}
char obuf[1 << 25], *p3 = obuf;
inline void pc(char c)
{
p3 - obuf <= (1 << 24) ? (*p3++ = c) : (fwrite(obuf, p3 - obuf, 1, stdout), p3 = obuf, *p3++ = c);
}
inline void write(int x)
{
if(x < 0) pc('-'), x = -x;
if(x == 0) pc('0');
static char c[20];
int tt = 0;
while(x) c[++tt] = x % 10 + '0', x /= 10;
while(tt) pc(c[tt--]);
}
int h[N], ne[N], e[N], idx;
void add(int a, int b)
{
e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}
int dfn1[N], dfn2[N], viti;
void dfs(int x)
{
dfn1[x] = ++viti;
for(register int i = h[x]; i; i = ne[i])
dfs(e[i]);
dfn2[x] = viti;
}
int ans1[M][K], ans2[K][M];
int c[N];
void dfs1(int x)
{
int t = to[a[x]];
for(register int i = 1; i <= big.size(); ++i)
ans2[i][a[x]] += c[i];
if(t) ++c[t];
for(register int i = h[x]; i; i = ne[i])
dfs1(e[i]);
if(t) --c[t];
}
int lowbit(int x)
{
return x & -x;
}
void modify(int x, int d)
{
for(register int i = x; i <= n; i += lowbit(i))
c[i] += d;
}
int getsum(int x)
{
int sum = 0;
for(register int i = x; i; i -= lowbit(i))
sum += c[i];
return sum;
}
int main()
{
n = read(), r = read(), q = read(), a[1] = read();
k = sqrt(n * 1.5);
for(register int i = 2; i <= n; ++i)
{
add(read(), i);
a[i] = read();
}
dfs(1);
for(register int i = 1; i <= n; ++i)
{
r1[a[i]].push_back(dfn1[i]);
r2[a[i]].push_back(dfn2[i]);
}
for(register int i = 1; i <= r; ++i)
{
len[i] = r1[i].size();
if(len[i] > k) big.push_back(i), to[i] = big.size();
sort(r1[i].begin(), r1[i].end());
sort(r2[i].begin(), r2[i].end());
}
dfs1(1);
memset(c, 0, sizeof(c));
for(register int i = 1; i <= big.size(); ++i)
{
for(int j : r1[big[i - 1]]) modify(j, 1);
for(register int j = 1; j <= n; ++j)
ans1[a[j]][i] += getsum(dfn2[j]) - getsum(dfn1[j]);
for(int j : r1[big[i - 1]]) modify(j, -1);
}
while(q--)
{
int a = read(), b = read();
if(len[a] <= k && len[b] <= k)
{
int ans = 0;
for(register int i = 0, j = 0, k = 0; i < len[a]; ++i)
{
while(j < len[b] && r1[b][j] <= r2[a][i]) ++j;
while(k < len[b] && r1[b][k] < r1[a][i]) ++k;
ans += j - k;
}
write(ans), pc('\n');
}
else if(len[a] > k)
write(ans2[to[a]][b]), pc('\n');
else
write(ans1[a][to[b]]), pc('\n');
}
fwrite(obuf, p3 - obuf, 1, stdout);
return 0;
}