BZOJ4381 : [POI2015]Odwiedziny / Luogu3591[POI2015]ODW - 分块+树剖
Solution
在步伐$pace$比较小的时候, 我们发现用前缀和直接维护会很快
而在$pace$比较大的时候, 则暴力往上跳会最优
设$blo= \sqrt{N}$
若$pace<=blo$, 则利用前缀和更新,
预处理复杂度$O(N \sqrt{N})$, 查询复杂度$O(1)$
若$pace>blo$,则利用树剖逐渐往上跳
总共要跳$N/pace$次, 一共有$logN$条轻重链, 复杂度为$O(logN+ \sqrt{N})$
代码实现比较麻烦, 我常数写的还很差, 水平低啊QAQ
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define rd read()
#define N 50005
#define M 240
#define R register
using namespace std; int n, blo, a[N], b[N], f[N][M], sum[N][M];
int fa[N], dep[N], top[N], sz[N], son[N], id[N], idf[N], cnt;
int head[N], tot; struct edge {
int nxt, to;
}e[N << ]; inline char nc(){
static char buf[], *p1=buf, *p2=buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, , , stdin), p1 == p2) ? EOF : *p1++;
}
inline int read(){
char ch = nc();int sum = ;
while(!(ch >= '' && ch <= '')) ch = nc();
while(ch >= '' && ch <= '') sum = sum * + ch - , ch = nc();
return sum;
} inline void add(int u, int v) {
e[++tot].to = v;
e[tot].nxt = head[u];
head[u] = tot;
} inline void sw(int &A, int &B) {
A ^= B; B ^= A; A ^= B;
} inline void dfs1(R int u) {
sz[u] = ;
for (R int i = head[u]; i; i = e[i].nxt) {
R int nt = e[i].to;
if (nt == fa[u]) continue;
f[nt][] = fa[nt] = u;
dep[nt] = dep[u] + ;
dfs1(nt);
sz[u] += sz[nt];
if (sz[nt] > sz[son[u]])
son[u] = nt;
}
} inline void dfs2(R int u) {
idf[id[u] = ++cnt] = u;
if (!son[u]) return;
top[son[u]] = top[u];
dfs2(son[u]);
for (R int i = head[u]; i; i = e[i].nxt) {
R int nt = e[i].to;
if (nt == fa[u] || nt == son[u]) continue;
top[nt] = nt;
dfs2(nt);
}
} inline int LCA(R int x, R int y) {
for (;top[x] != top[y]; ) {
if (dep[top[x]] < dep[top[y]]) sw(x, y);
x = fa[top[x]];
}
if (dep[x] < dep[y]) sw(x, y);
return y;
} inline int work1(R int x, R int y, R int pace) {
R int lca = LCA(x, y), len = dep[x] + dep[y] - * dep[lca], res = ;
if (len % pace) {
res += a[y];
y = f[y][len % pace];
len -= len % pace;
}
len = dep[x] - dep[lca];
if (len % pace == ) {
res += sum[x][pace] - sum[lca][pace];
res += sum[y][pace] - sum[lca][pace];
res += a[lca];
return res;
}
R int tmp = f[lca][pace - len % pace];
res += sum[x][pace] - sum[tmp][pace];
if (dep[y] < dep[lca]) return res;
len = dep[y] - dep[lca];
tmp = f[lca][pace - len % pace];
res += sum[y][pace] - sum[tmp][pace];
return res;
} inline int up(R int x, R int d) {
R int y = top[x];
for (; x && dep[x] - dep[y] < d;) {
d -= dep[x] - dep[y] + ;
x = fa[top[x]];
y = top[x];
}
if (!x) return ;
return idf[id[x] - d];
} inline int work2(R int x, R int y, R int pace) {
R int lca = LCA(x, y), len = dep[x] + dep[y] - * dep[lca], res = ;
if (len % pace) {
res += a[y];
y = up(y, len % pace);
len -= len % pace;
}
len = dep[x] - dep[lca];
if (len % pace == ) {
while (x && dep[x] > dep[lca])
res += a[x], x = up(x, pace);
while (y && dep[y] > dep[lca])
res += a[y], y = up(y, pace);
res += a[lca];
return res;
}
while (x && dep[x] > dep[lca])
res += a[x], x = up(x, pace);
while (y && dep[y] > dep[lca])
res += a[y], y = up(y, pace);
return res;
} int main()
{
n = rd; blo = sqrt(n);
for (R int i = ; i <= n; ++i)
a[i] = rd;
for (R int i = ; i < n; ++i) {
int u = rd, v = rd;
add(u, v); add(v, u);
}
dep[] = ; dfs1();
top[] = ; dfs2();
for (R int j = ; j <= blo; ++j)
for (R int i = ; i <= n; ++i)
f[i][j] = f[f[i][j - ]][];
for (R int j = ; j <= blo; ++j)
for (R int i = ; i <= n; ++i)
sum[i][j] = a[i];
for (R int j = ; j <= blo; ++j)
for (R int i = ; i <= n; ++i) {
int x = idf[i];
sum[x][j] += sum[f[x][j]][j];
}
for (R int i = ; i <= n; ++i) b[i] = rd;
for (R int i = ; i < n; ++i) {
R int x = rd;
if (x <= blo) printf("%d\n", work1(b[i], b[i + ], x));
else printf("%d\n", work2(b[i], b[i + ], x));
}
}
BZOJ4381 : [POI2015]Odwiedziny / Luogu3591[POI2015]ODW - 分块+树剖的更多相关文章
- HDU5840 Problem This world need more Zhu 分块 树剖
给一颗n个点的有点权的树,有m个询问,对于每个询问u,v,k,首先将点u到点v的最短路径上的所有点按顺序编号,u的编号为1,求树链上所有点的新编号cnt满足cnt%k==0的点的权值的最大值.n,m, ...
- [POI2015]Odwiedziny
[POI2015]Odwiedziny 题目大意: 一棵\(n(n\le5\times10^4)\)个点的树,\(n\)次询问从一个点到另一个点的路径上,每次跳\(k\)个点,所经过的点权和. 思路: ...
- 【BZOJ 3295】动态逆序对 - 分块+树状数组
题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...
- 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...
- 【UOJ#435】【集训队作业2018】Simple Tree 分块+树链剖分
题目大意: 有一棵有根树,根为 1 ,点有点权.现在有 m 次操作,操作有 3 种:1 x y w ,将 x 到 y 的路径上的点点权加上 w (其中 w=±1w=±1 ):2 x y ,询问在 x ...
- 【bzoj2141】排队 分块+树状数组
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别, ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...
- BZOJ 4765(分块+树状数组)
题面 传送门 "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些 .普通计算机能计算数列区间和,而普通计算姬能计算树中子树和.更 ...
随机推荐
- 将SQL for xml path('')中转义的字符正常显示
在工作中出现的发送邮件的时候:因为邮件内容中有链接,并且多个拼接在一起的,于是用了for xml path(). 但是,这样显示出来的链接时会将路径中的<,>,&符号转 ...
- PAT 乙级 1086 就不告诉你 (15 分)
1086 就不告诉你 (15 分) 做作业的时候,邻座的小盆友问你:“五乘以七等于多少?”你应该不失礼貌地围笑着告诉他:“五十三.”本题就要求你,对任何一对给定的正整数,倒着输出它们的乘积. 输入格式 ...
- Git从远程clone项目报错cannot open git-upload-pack,将http.sslVerify设为false即可
通过HTTPS访问Git远程仓库,如果服务器的SSL证书未经过第三方机构签署,那么Git就会报错 通过https访问Git远程仓库,如果服务器的SSL证书没有经过第三方机构签署,就会出现cannot ...
- 通过WebClient模拟post上传文件到服务器
写在前面 最近一直在研究sharepoint的文档库,在上传文件到文档库的过程中,需要模拟post请求,也查找了几种模拟方式,webclient算是比较简单的方式. 一个例子 这里写一个简单接受pos ...
- POJ1003 – Hangover (基础)
Hangover Description How far can you make a stack of cards overhang a table? If you have one card, ...
- atnodes命令使用方法
一条命令可以同时执行多台机器,结果会输出列表. atnodes -L 'grep -c "查询订单列表,userId=bing.wang03" /home/w/www/order- ...
- 性能测试day05_Jmeter学习
今天来学习下jmeter这个性能测试工具,虽然说性能测试最主要的是整个性能的思路,但是也少不了工具的帮忙,从以前主流的LR到jmeter的兴起,不过对于性能测试来说,个人感觉jmeter比较适合接口性 ...
- IntelliJ IDEA 调试技巧
程序员的工作内容,有不少的时间是用在调试代码上.可以说不是在调试代码,就是即将调试代码. 掌握调试代码的一些技巧,在使用IDE提供的debugger时会快速定位问题的方式. 1.多线程调试 在多线程应 ...
- centos6.5部署redmine3.2
ruby 2.1 + rails 4.2+ mysql 5.6 +centos6.5 + rvm 1.29 1.基本的软件环境 yum -y install libyaml-devel zlib-de ...
- python3爬虫入门程序
适用于有且只有一点Python3和网页基础的朋友,大牛&路人请绕道 (本文很多废话,第一次在网上长篇大论,所以激动的停不下来,如果有大佬路过,也希望不要直接绕道,烦请指点一二) 感谢博客园给了 ...