社区讨论
求问常数
学术版参与者 2已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mi8ujhyu
- 此快照首次捕获于
- 2025/11/21 20:38 4 个月前
- 此快照最后确认于
- 2025/11/21 21:20 4 个月前
猎奇分块做法,时间复杂度 。求问为什么在 At 和 自己学校的网站上都会 TLE。自己学校网站上极限数据要跑 4s。是常数太大了还是时间复杂度确实有问题,虚心请教!
代码
CPP#include <bits/stdc++.h>
#define ll long long
#define rint register int
using namespace std;
const int maxn = 2e5 + 5, maxb = 500;
int n;
ll f[maxn], ans[maxn];
unordered_map <int, ll> key[maxn];
// 以 i 为根 j 子树中小于 j 的个数
int head[maxn], ecnt;
struct Edge {
int nxt, to;
} edge[maxn << 1];
inline void add(int from, int to) {
edge[++ecnt] = {head[from], to};
head[from] = ecnt;
return;
}
struct chunking {
int block, a[maxn], b[maxn], pos[maxn], l[maxb], r[maxb];
void init() {
block = sqrt(n);
for(rint i = 1; i <= n; i++) {
pos[i] = (i + block - 1) / block;
b[i] = a[i];
if(pos[i] != pos[i - 1]) l[pos[i]] = i;
r[pos[i]] = max(r[pos[i]], i);
}
for(rint i = 1; i <= pos[n]; i++) sort(b + l[i], b + r[i] + 1);
return;
}
ll qry(int x, int y, int k) {
ll res = 0;
if(pos[x] == pos[y]) {
for(rint i = x; i <= y; i++) res += (a[i] < k);
return res;
}
for(rint i = x; pos[i] == pos[x]; i++) res += (a[i] < k);
for(rint i = y; pos[i] == pos[y]; i--) res += (a[i] < k);
for(rint i = pos[x] + 1; i <= pos[y] - 1; i++)
if(b[l[i]] < k) res += lower_bound(b + l[i], b + r[i] + 1, k) - (b + l[i]);
return res;
}
} ch;
struct tree_cutting {
int tim, siz[maxn], dfn[maxn];
void dfs(int x, int fa) {
siz[x] = 1, dfn[x] = ++tim;
ch.a[dfn[x]] = x;
for(rint i = head[x]; i; i = edge[i].nxt) {
int to = edge[i].to;
if(to == fa) continue;
dfs(to, x);
siz[x] += siz[to];
}
return;
}
ll qry_sub(int x, int k) { return ch.qry(dfn[x], dfn[x] + siz[x] - 1, k); }
} tc;
struct dynamic_programing {
void dfs1(int x, int fa) {
ll sum = 0;
for(rint i = head[x]; i; i = edge[i].nxt) {
int to = edge[i].to;
if(to == fa) continue;
key[x][to] = tc.qry_sub(to, to);
sum += tc.qry_sub(to, fa);
dfs1(to, x);
f[x] += f[to] + key[x][to];
}
if(fa) key[x][fa] = fa - 1 - sum - (x < fa);
return;
}
void dfs2(int x, int fa) {
ans[x] = f[x] + x - 1;
for(rint i = head[x]; i; i = edge[i].nxt) {
int to = edge[i].to;
if(to == fa) continue;
ll f_x = f[x], f_to = f[to];
f[x] -= f[to] + key[x][to];
f[to] += f[x] + key[to][x];
dfs2(to, x);
f[x] = f_x, f[to] = f_to;
}
return;
}
} dp;
int read() {
int k = 0, f = 1;
char c = getchar();
while(c < '0' || '9' < c) f = (c == '-') ? -1 : 1, c = getchar();
while('0' <= c && c <= '9') k = k * 10 + c - '0', c = getchar();
return k * f;
}
void write(ll x) {
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main() {
n = read();
int u, v;
for(rint i = 1; i < n; i++) {
u = read(), v = read();
add(u, v), add(v, u);
}
tc.dfs(1, 0), ch.init();
dp.dfs1(1, 0), dp.dfs2(1, 0);
for(rint i = 1; i <= n; i++) write(ans[i]), putchar(' ');
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...