社区讨论
WA on #21 求调
P10421[蓝桥杯 2023 国 A] 树上的路径参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mjh5kd1p
- 此快照首次捕获于
- 2025/12/22 20:49 3 个月前
- 此快照最后确认于
- 2025/12/25 14:20 2 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
#define intt long long
const int N = 1000005, M = 2000005;
int n,l,r,rt,u,cnt,head[N];
int ver[M],nxt[M],dep;
int siz[N],s[N];
bool tag[N];
intt ans;
struct seg
{
intt c[N];
void add(int x,int y)
{
while (x <= min(dep,r))
{
c[x] += y;
x += (x & (-x));
}
}
intt query(int x)
{
x = min(x,min(dep,r));
intt res = 0;
while (x)
{
res += c[x];
x -= (x & (-x));
}
return res;
}
void clean()
{
for (int i=1;i<=dep;i++)
{
c[i] = 0;
}
return;
}
}t,T;
void add(int x,int y)
{
ver[++cnt] = y;
nxt[cnt] = head[x];
head[x] = cnt;
}
void dfs(int u)
{
tag[u] = 1;
s[u] = siz[u] = 1;
for (int i=head[u];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
dfs(v);
siz[u] += siz[v];
s[u] = max(s[u],siz[v]);
}
tag[u] = 0;
}
void depth(int u,int len)
{
tag[u] = 1;
dep = max(dep,len);
for (int i=head[u];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
depth(v,len+1);
}
tag[u] = 0;
}
void heavy(int u,int tot)
{
tag[u] = 1;
for (int i=head[u];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
heavy(v,tot);
}
s[u] = max(s[u],tot-siz[u]);
if (s[u] < s[rt]) rt = u;
tag[u] = 0;
}
void solve(int u,int len)
{
tag[u] = 1;
if (len > r) return;
if (l <= len && len <= r) ans += len;
if (l-len-1 >= 1) ans += (T.query(r-len) - T.query(l-len-1)) + (t.query(r-len) - t.query(l-len-1)) * len;
else ans += T.query(r-len) + t.query(r-len) * len;
// cout << u << ' ' << len << ' ' << ans << endl;
for (int i=head[u];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
solve(v,len+1);
}
tag[u] = 0;
}
void update(int u,int len,int x)
{
tag[u] = 1;
if (len > r) return;
t.add(len,x);
// cout << "t.add: " << len << ' ' << x << endl;
T.add(len,x*len);
// cout << "T.add: " << len << ' ' << x*len << endl;
for (int i=head[u];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
update(v,len+1,x);
}
tag[u] = 0;
}
void calc(int u)
{
rt = u; dfs(u);
heavy(u,siz[u]);
dep = 0; depth(rt,0);
// cout << rt << ' ' << dep << endl;
t.clean();
T.clean();
tag[rt] = 1;
for (int i=head[rt];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
solve(v,1);
update(v,1,1);
}
for (int i=head[rt];i;i=nxt[i])
{
int v = ver[i];
if (tag[v]) continue;
calc(v);
}
}
int main()
{
scanf("%d%d%d",&n,&l,&r);
for (int i=2;i<=n;i++)
{
scanf("%d",&u);
add(u,i); add(i,u);
}
calc(1);
printf("%lld",ans);
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...