社区讨论
为什么跑的这么慢?
P4074[WC2013] 糖果公园参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mjnnqoev
- 此快照首次捕获于
- 2025/12/27 10:04 2 个月前
- 此快照最后确认于
- 2025/12/28 21:00 2 个月前
写的是括号序树上莫队,但为什么跑这么慢?
以及为什么块长要调到25000才能过,别的块长过不了,按理来说带修莫队块长不是 最优吗?LCA用的最弱的倍增,但复杂度瓶颈应该不在这吧。
CPP#include<bits/stdc++.h>
// #define int long long
#define pb emplace_back
#define pii pair <int, int>
#define root 1, 1, n
#define id(p) (((p) + B - 1) / B)
#define R(id) ((id) * B)
#define L(id) ((id) * B - B + 1)
inline int read() {
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
using namespace std;
const int N = 2e5 + 5, K = 20;
int n, m, q, a[N * 2], B, nl = 1, nr = 0, nt = 0;
long long res = 0, ans[N];
int v[N], w[N], c[N], ldfn[N], rdfn[N], ar, cnt[N], vis[N], f[N][K], d[N];
vector <int> edge[N];
struct Q{
int l, r, t, addi, id;
}qa[N], op[N];
inline void add(const int& p){
if (!vis[a[p]]){
vis[a[p]] = 1;
res += 1ll * w[++ cnt[c[a[p]]]] * v[c[a[p]]];
}else{
vis[a[p]] = 0;
res -= 1ll * w[cnt[c[a[p]]] --] * v[c[a[p]]];
}
}
inline void del(const int& p){
if (!vis[a[p]]){
vis[a[p]] = 1;
res += 1ll * w[++ cnt[c[a[p]]]] * v[c[a[p]]];
}else{
vis[a[p]] = 0;
res -= 1ll * w[cnt[c[a[p]]] --] * v[c[a[p]]];
}
}
inline void update(const int& t){
int p = op[t].id;
if (ldfn[p] >= nl && ldfn[p] <= nr) del(ldfn[p]);
if (rdfn[p] >= nl && rdfn[p] <= nr) del(rdfn[p]);
swap(op[t].t, c[p]);
if (ldfn[p] >= nl && ldfn[p] <= nr) add(ldfn[p]);
if (rdfn[p] >= nl && rdfn[p] <= nr) add(rdfn[p]);
}
inline void dfs(const int& p, const int& fa){
f[p][0] = fa;
d[p] = d[fa] + 1;
for (int i = 1; i < K; i ++) f[p][i] = f[f[p][i - 1]][i - 1];
a[++ ar] = p;
ldfn[p] = ar;
for (auto to : edge[p]) if (to != fa){
dfs(to, p);
}
a[++ ar] = p;
rdfn[p] = ar;
}
int LCA(int a, int b){
if (d[a] < d[b]) swap(a, b);
for (int k = K - 1; k >= 0; k --)
if (d[f[a][k]] >= d[b])
a = f[a][k];
if (a == b) return a;
for (int k = K - 1; k >= 0; k --)
if (f[a][k] != f[b][k])
a = f[a][k], b = f[b][k];
return f[a][0];
}
signed main(){
// cin.tie(0)->sync_with_stdio(0);
n = read(), m = read(), q = read();
B = 25000;
for (int i = 1; i <= m; i ++) v[i] = read();
for (int i = 1; i <= n; i ++) w[i] = read();
for (int i = 1; i < n; i ++){
int u, v;
u = read(), v = read();
edge[u].pb(v);
edge[v].pb(u);
}
for (int i = 1; i <= n; i ++) c[i] = read();
int t = 0;
dfs(1, 0);
for (int i = 1; i <= q; i ++){
int c;
c = read();
if (c){
int &l = qa[i - t].l, &r = qa[i - t].r;
l = read(), r = read();qa[i - t].id = i - t, qa[i - t].t = t;
if (ldfn[l] > ldfn[r]) swap(l, r);
int lca = LCA(l, r), flag = 0;
if (lca == l) l = ldfn[l], r = ldfn[r];
else l = rdfn[l], r = ldfn[r], qa[i - t].addi = lca;
}else{
t ++;
op[t].id = read(), op[t].t = read();
}
}
sort(qa + 1, qa + 1 + q - t, [](Q a, Q b){
return id(a.l) == id(b.l) && id(a.r) == id(b.r) ?
a.t < b.t : (a.l == b.l ? a.r < b.r : a.l < b.l);
});
for (int i = 1; i <= q - t; i ++){
auto [l, r, t, lca, ID] = qa[i];
while (nl > l) add(-- nl);
while (nr < r) add(++ nr);
while (nl < l) del(nl ++);
while (nr > r) del(nr --);
while (nt < t) update(++ nt);
while (nt > t) update(nt --);
if (lca) add(ldfn[lca]);
ans[ID] = res;
if (lca) del(ldfn[lca]);
}
for (int i = 1; i <= q - t; i ++){
cout << ans[i] << '\n';
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...