QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#90791 | #5830. 树 | joke3579 | 0 | 0ms | 0kb | C++14 | 7.4kb | 2023-03-25 12:07:58 | 2023-03-25 12:07:59 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
namespace Fread { const int SIZE = (1 << 18); char buf[SIZE], *p1 = buf, *p2 = buf; inline char getchar() {return (p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, SIZE, stdin), p1 == p2) ? EOF : *p1++);} }
namespace Fwrite { const int SIZE = (1 << 18); char buf[SIZE], *S = buf, *T = buf+SIZE; inline void flush(){ fwrite(buf, 1, S-buf, stdout), S = buf; } struct NTR{ ~NTR() { flush(); } }ztr;inline void putchar(char c){ *S++ = c; if(S == T) flush(); } }
#ifdef ONLINE_JUDGE
#define getchar Fread::getchar
#define putchar Fwrite::putchar
#endif
namespace Fastio{
struct Reader{ template <typename T> Reader & operator >> (T & x) {char c = getchar(); bool f = false;while (c < '0' or c > '9') { if (c == '-') f = true;c = getchar();} x = 0;while(c >= '0' and c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} if (f) x = -x;return *this;}Reader&operator>>(char&c){ c=getchar();while(c=='\n'||c==' '||c=='\r')c=getchar();return *this;}Reader&operator>>(char*str){ int len=0;char c=getchar(); while(c=='\n'||c==' '||c=='\r')c=getchar(); while(c!='\n'&&c!=' '&&c!='\r')str[len++]=c,c=getchar(); str[len]='\0'; return *this;}Reader(){}}cin;
struct Writer{ template <typename T> Writer & operator << (T x) {if(x == 0) return putchar('0'), *this;if(x < 0) putchar('-'), x = -x;static int sta[45], top = 0; while (x) sta[++top] = x %10, x /= 10; while (top) putchar(sta[top] + '0'), --top; return *this;} Writer&operator<<(char c){putchar(c);return*this;}Writer&operator<<(const char*str){int cur=0;while(str[cur])putchar(str[cur++]);return *this;}Writer(){}}cout;
} const char endl = '\n';
#define cin Fastio :: cin
#define cout Fastio :: cout
#define inline __attribute__((__gnu_inline__, __always_inline__, __artificial__)) inline
using pii = pair<int,int>; using vi = vector<int>; using vp = vector<pii>; using ll = long long;
using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
template<typename T1, typename T2> T1 max(T1 a, T2 b) { return a > b ? a : b; }
template<typename T1, typename T2> T1 min(T1 a, T2 b) { return a < b ? a : b; }
#define multi int _T_; cin >> _T_; for (int TestNo = 1; TestNo <= _T_; ++ TestNo)
#define timer cerr << 1. * clock() / CLOCKS_PER_SEC << '\n';
#define iot ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
#define eb emplace_back
#define pb pop_back
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fll;
int n, q, t1, t2, va[N];
vp qu[N]; ll ans[N];
int head[N], mlc;
struct ep {
int to, nxt;
} e[N << 1];
inline void adde(int u, int v) {
e[++ mlc] = { v, head[u] }; head[u] = mlc;
}
int dep[N], mxdp[N], fa[N], son[N], dfn[N], stp;
void dfs1(int u) {
dep[u] = mxdp[u] = dep[fa[u]] + 1;
for (int i = head[u], v; i; i = e[i].nxt) {
dfs1(v = e[i].to), mxdp[u] = max(mxdp[u], mxdp[v]);
if (mxdp[v] > mxdp[son[u]]) son[u] = v;
} if (!son[u]) son[u] = u;
}
int f[31][N][2], g[31][N];
inline ll __calc(int b, int id, int lbit) {
if (lbit <= (1 << b)) return f[b][id][1] - f[b][id + lbit][1];
else return f[b][id][1] - f[b][id + (1 << b)][1] + f[b][id + (1 << b)][0] - f[b][id + lbit][0];
}
inline ll calc(int b, int id, int k, int nowdep) {
if (k > nowdep) return g[b][id];
if (b > 20) return f[b][id][1] - f[b][id + k][1];
int hbit = k >> (b + 1) << (b + 1);
return g[b][id] - g[b][id + hbit] + __calc(b, id + hbit, k - hbit);
}
void dfs2(int u) {
dfn[u] = ++ stp;
if (son[u] != u) dfs2(son[u]);
for (int i = head[u], v; i; i = e[i].nxt) if ((v = e[i].to) != son[u]) {
dfs2(v);
rep(i,0,30) pre(j,mxdp[v] - dep[v],0) {
f[i][dfn[u] + 1 + j][0] += f[i][dfn[v] + j][0];
f[i][dfn[u] + 1 + j][1] += f[i][dfn[v] + j][1];
g[i][dfn[u] + 1 + j] += g[i][dfn[v] + j];
}
}
int id = dfn[u];
rep(i,0,30) f[i][id][va[u] >> i & 1] ++;
if (son[u] != u) {
rep(i,0,30) rep(j,0,1) f[i][id][j] += f[i][id + 1][j];
rep(i,0,30) {
if ((2ll << i) <= mxdp[u] - dep[u]) g[i][id] = f[i][id][1] - f[i][id + (1 << i)][1] + f[i][id + (1 << i)][0] - f[i][id + (2 << i)][0] + g[i][id + (2 << i)];
else if ((1 << i) <= mxdp[u] - dep[u]) g[i][id] = f[i][id][1] - f[i][id + (1 << i)][1] + f[i][id + (1 << i)][0];
else g[i][id] = f[i][id][1];
}
} else rep(i,0,30) g[i][id] = f[i][id][1];
for (auto [k, id] : qu[u]) {
k = min(k + 1, mxdp[u] - dep[u] + 1);
rep(i,0,30) ans[id] += (calc(i, dfn[u], k, mxdp[u] - dep[u]) << i);
}
}
int main() {
file(tree);
cin >> n;
rep(i,1,n) cin >> va[i];
rep(i,2,n) cin >> fa[i], adde(fa[i], i);
cin >> q;
rep(i,1,q) cin >> t1 >> t2, qu[t1].eb(t2, i);
dfs1(1), dfs2(1);
rep(i,1,q) cout << ans[i] << '\n';
}
/*
不离线可能没法做,我们考虑离线
询问插入对应点 这样先 dfs 维护完子树内信息 再静态查询
考虑用长剖合并子树 k 深度内信息;位运算考虑拆位
设 g(b, id) 表示 u 在长剖数组内的位置是 id,g(b, id + k) 表示 u 子树内小于等于 k 深度的所有点对应的答案在 2^b 项系数
f(b, id, 0/1) 的定义类似,是 \sum v 在 2^b 项系数
首先考虑统计答案 假设本节点在长剖数组里的位置是 id
我们按位统计
1. 如果这一位 b 高于 log2(max_depth) 发现这位不可能被 dep 进位,直接统计 (f(b, id, 1) - f(b, id, 0)) * 2^b 即可
2. 如果 k > max_depth 直接统计 g(b, id) * 2^b 即可
3. 反之我们需要做进位,先剥离 k 的低 i 位和剩下的部分;记低 i 位是 lbit,剩下的部分是 hbit,答案首先统计 (g(b, w) - g(b, w + hbit)) * 2^b
然后是低 i 位,我们发现它进位的部分只可能是一个后缀 考虑这个后缀的形态
如果这个后缀的最高位没到 b 位,那退化成 1. 状态
反之这个后缀的长度一定形如 2^b,两次差分即可
然后考虑计算 f 和 g
首先我们不加更改地对除长链外的儿子做合并,这复杂度是 O(n) 的(吧)
这是两个同等深度的后缀和数组做合并,不需要额外计算信息
然后对 f 数组合并进当前节点的贡献,也就是 f(i, id, v[u] >> i & 1) + 1
最后对 f 合并长儿子,并在这个过程中对 g 计算子树贡献和,也就是 g(b, id)
如果没有长儿子,退化成叶子:f 不用合并除当前节点外的贡献、g(b, id) = f(b, id, 1)
反之首先合并 f,简单地维护 f(b, id, 0/1) 处的前缀和性质
然后做类似上面的统计答案 这时的阈值是长链的长度
如果当前位超过 长链长度*2 则连进位都不用考虑,直接退化成 f(b, id, 1)
反之讨论是否超过长链长度
如果超过了则只需要考虑最高位的进位,我们仍然有上面的性质,即后缀长度形如 2^b
答案就是 f(b, id, 1) - f(b, id + 2^b, 1) + f(b, id + 2^b, 0),这里第二次差分不用考虑长度
如果没超过,我们发现需要统计一段 答案在 2^b 项的系数,是 g(b, id + 2^{b + 1}),这在先前已经得到了
答案就是 f(b, id, 1) - f(b, id + 2^b, 1) + f(b, id + 2^b, 0) - f(b, id + 2^{b + 1}, 0) + g(b, id + 2^{b + 1})
大概没了
*/
详细
Test #1:
score: 0
Dangerous Syscalls
input:
2000 946347867 341162491 202762650 295215762 254064439 66267204 693162580 357612557 492940637 939526638 59775103 374919339 144042807 861369313 651043728 999024805 439554916 167782038 597475252 56704409 69846137 22185655 79439847 769194737 145071391 226046618 915359433 392527325 84982946 54584098 827...
output:
result:
Test #2:
score: 0
Dangerous Syscalls
input:
99999 792064428 473106195 799314986 65440734 948726345 442414256 280245405 873012700 466192412 899092866 283555341 657824017 963883713 793944180 767444438 105576842 542107696 580140098 65321660 381184238 584604194 397414881 861590124 309323011 217641157 120832524 303744205 961590116 110259426 380351...
output:
result:
Test #3:
score: 0
Dangerous Syscalls
input:
1000000 947727010 179844140 923847675 171881267 5552129 974443359 989307850 869400987 126992154 527448411 141137718 136124474 917813105 392020809 79012342 473860575 969007624 833563354 90169336 878445705 84352622 403307122 733751738 670851448 942399068 731541999 101293644 545785337 964751520 9168003...
output:
result:
Test #4:
score: 0
Dangerous Syscalls
input:
1000000 264862971 751386013 921867736 711577153 262726588 565608444 975324815 440219681 107888226 928241413 729126923 283912914 86248857 896446999 12839598 651796991 139813366 105131395 341646170 839485925 939265720 844548518 102280410 457829889 8602879 737140565 17206920 974175632 535833885 8373832...
output:
result:
Test #5:
score: 0
Dangerous Syscalls
input:
1000000 978606419 773027389 111265179 979476504 280718851 476857501 751854950 579263969 848569548 781051974 31782627 533831186 812822170 111553645 297770650 331144396 676977983 2236128 258203325 75591120 676466973 60056446 494411414 286185093 92474576 173276071 535648669 87210101 355790411 880267291...
output:
result:
Test #6:
score: 0
Dangerous Syscalls
input:
1000000 952470566 585754087 120174600 401525004 458588768 5487567 31210348 446333263 231409083 521960132 457721893 866842852 925207283 16805978 4706826 99640835 619272676 136536623 459247161 308807462 633687300 717271369 23906473 865522890 173799280 424309108 719410673 118906385 110627845 730629403 ...
output:
result:
Test #7:
score: 0
Dangerous Syscalls
input:
1000000 732367509 105027907 958920212 886798715 102486738 813075884 301085392 242303497 979657287 944859684 307768 438158233 561755409 740706505 791145209 283862713 828081846 771569552 59044985 600549571 191330226 438693570 36976319 810654215 220068818 771875421 740642902 839964155 206129566 2065543...
output:
result:
Test #8:
score: 0
Dangerous Syscalls
input:
1000000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
output:
result:
Test #9:
score: 0
Dangerous Syscalls
input:
1000000 465660691 982007525 816592310 377030959 572981469 679249520 86377999 709561525 940473306 35102782 886143915 792819787 903287397 264564177 857982095 91486434 217197704 123118964 383387342 820268798 497623987 255010796 607884194 848568529 38169627 197987657 421323589 664004905 485409127 696844...
output:
result:
Test #10:
score: 0
Dangerous Syscalls
input:
1000000 665830082 788228483 245541444 289601309 641764988 150723484 925214020 557415731 310210969 379707835 517820381 883917428 134445288 775557009 444476671 89856268 655841087 888410254 37788122 694551869 563331754 488108584 839551943 415095075 445425438 35452604 562044723 640544531 146258096 66852...