首页 技术 正文
技术 2022年11月18日
0 收藏 979 点赞 3,035 浏览 2541 个字

对树的dfs序分块,打开了新世界的大门233

第一关键字是l所在的块,第二关键字是r所在的块,第三关键字是时间,分完块后暴力莫队即可

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100003;
void read(int &k) {
k = 0; int fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 1) + (k << 3) + c - '0';
k = k * fh;
}bool vis[N];
ll A[N], ans = 0;
struct TIME {int x, y, la;} Time[N];
struct edge {int nxt, to;} E[N << 1];
struct node {int l, r, lca, id, tim;} Q[N];
int cal[N], n, m, q, V[N], W[N], f[N][17], deep[N], bel[N << 1];
int point[N], color[N], colorchange[N], pos[N << 1], L[N], R[N], cnt = 0;void ins(int x, int y) {E[++cnt].nxt = point[x]; E[cnt].to = y; point[x] = cnt;}
void _(int x, int fa) {
pos[L[x] = ++cnt] = x;
for(int i = 1; i <= 16; ++i) {f[x][i] = f[f[x][i - 1]][i - 1]; if (f[x][i] == 0) break;}
for(int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if (E[tmp].to != fa)
{deep[E[tmp].to] = deep[x] + 1; f[E[tmp].to][0] = x; _(E[tmp].to, x);}
pos[R[x] = ++cnt] = x;
}
int LCA(int x, int y) {
if (deep[x] < deep[y]) swap(x, y);
int d = deep[x] - deep[y];
for(int i = 0; i <= 16; ++i) if (d & (1 << i)) x = f[x][i];
if (x == y) return x;
for(int i = 16; i >= 0; --i) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
}
void update(int x) {
if (vis[x]) {ans -= 1ll * V[color[x]] * W[cal[color[x]]]; --cal[color[x]];}
else {++cal[color[x]]; ans += 1ll * V[color[x]] * W[cal[color[x]]];}
vis[x] = !vis[x];
}
void change(int a, int b) {
if (vis[a]) {update(a); color[a] = b; update(a);}
else color[a] = b;
}
void Timechange(int &a, int b) {
while (a < b) {++a; change(Time[a].x, Time[a].y);}
while (a > b) {change(Time[a].x, Time[a].la); --a;}
}
bool cmp(node A, node B) {return bel[A.l] == bel[B.l] ? (bel[A.r] == bel[B.r] ? A.tim < B.tim : A.r < B.r) : A.l < B.l;}int main() {
read(n); read(m); read(q);
for(int i = 1; i <= m; ++i) read(V[i]);
for(int i = 1; i <= n; ++i) read(W[i]);
int op, u, v, timecount = 0, tmp = 0, lca;
for(int i = 1; i < n; ++i) {
read(u); read(v);
ins(u, v); ins(v, u);
}
for(int i = 1; i <= n; ++i) read(color[i]), colorchange[i] = color[i];cnt = 0;
_(1, 0);for(int i = 1; i <= q; ++i) {
read(op); read(u); read(v);
if (op == 0) {Time[++timecount] = (TIME) {u, v, colorchange[u]}; colorchange[u] = v;}
else {
if (L[u] > L[v]) swap(u, v);
lca = LCA(u, v);
if (lca == u) Q[++tmp] = (node) {L[u], L[v], 0, tmp, timecount};
else Q[++tmp] = (node) {R[u], L[v], lca, tmp, timecount};
}
}int nn = n << 1, sq = pow(nn, 2.0 / 3) * 0.5, sign = 0; cnt = 1;
for(int i = 1; i <= nn; ++i) {
bel[i] = sign;
++cnt; if (cnt > sq) {cnt = 1; ++sign;}
}sort(Q + 1, Q + tmp + 1, cmp);int l = 1, r = 0, now = 0, tol, tor;
for(int i = 1; i <= tmp; ++i) {
tol = Q[i].l; tor = Q[i].r;
Timechange(now, Q[i].tim);
while (l < tol) update(pos[l++]);
while (l > tol) update(pos[--l]);
while (r < tor) update(pos[++r]);
while (r > tor) update(pos[r--]);
if (Q[i].lca) update(Q[i].lca);
A[Q[i].id] = ans;
if (Q[i].lca) update(Q[i].lca);
}for(int i = 1; i <= tmp; ++i) printf("%lld\n", A[i]);return 0;
}

dfs序分块战术核导弹速度超快~

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,082
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,557
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,406
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,179
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,815
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898