这题搞了我一下午……因为一些傻X的问题……

对于步长大于sqrt(n)的询问,我们可以直接暴力求解

然后,我们可以事先预处理出d[u][step]表示u往上跳,每次跳step步,直到跳到不能跳为止,所获得的分数,其中step<=K

那么对于步长小于sqrt(n)的询问,我们直接查表然后一系列运算即可

各种细节自己yy吧

复杂度应该是O(nsqrt(n)logn)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define N 50004
#define M 100005 using namespace std;
inline int read(){
int ret=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9'){
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
} struct edge{
int adj,next;
edge(){}
edge(int _adj,int _next):adj(_adj),next(_next){}
} e[M];
int n,g[N],m;
void AddEdge(int u,int v){
e[++m]=edge(v,g[u]);g[u]=m;
e[++m]=edge(u,g[v]);g[v]=m;
} const int K=500;
int a[N],f[N][23],d[N][K+5];
int fa[N],deep[N];
void dfs(int u){
deep[u]=deep[fa[u]]+1;
int v=fa[u];
for (int i=1;i<=K;++i,v=fa[v])
d[u][i]=d[v][i]+a[u];
for (int i=g[u];i;i=e[i].next){
int v=e[i].adj;
if (v==fa[u]) continue;
fa[v]=u;
dfs(v);
}
} void precompute(){
fa[1]=fa[0]=0;deep[0]=0;
memset(d[0],0,sizeof(d[0]));
dfs(1);
for (int i=1;i<=n;++i) f[i][0]=fa[i];
memset(f[0],0,sizeof(f[0]));
for (int k=1;k<=20;++k)
for (int i=1;i<=n;++i)
f[i][k]=f[f[i][k-1]][k-1];
} int jump(int u,int step){
for (int k=0;k<=20;++k)if ((step&(1<<k))>0)u=f[u][k];
return u;
}
int qlca(int u,int v){
if (deep[u]<deep[v]) swap(u,v);
u=jump(u,deep[u]-deep[v]);
for (int k=20;k>=0;--k)if (f[u][k]!=f[v][k])u=f[u][k],v=f[v][k];
return u==v?u:fa[u];
} int s[N],t[N];
int main(){
n=read();
for (int i=1;i<=n;++i) a[i]=read();
memset(g,0,sizeof(g));m=1;
for (int i=1;i<n;++i) AddEdge(read(),read());
precompute();
for (int i=1;i<=n;++i) t[i-1]=s[i]=read();
for (int i=1;i<n;++i){
int step=read(),lca=qlca(s[i],t[i]),u=s[i],v=t[i],res=0;
if ((deep[u]+deep[v]-2*deep[lca])%step>0){
res+=a[v];
v=jump(v,(deep[u]+deep[v]-2*deep[lca])%step);
}
if (deep[lca]%step==deep[u]%step) res+=a[lca];
if (step<=K){
int top1=jump(lca,(deep[lca]%step-deep[u]%step+step)%step),top2=jump(lca,(deep[lca]%step-deep[v]%step+step)%step);
res+=d[u][step]-d[top1][step]+d[v][step]-d[top2][step];
}
else for (int j=0;j<2;++j)
for (swap(u,v);deep[u]>deep[lca];u=jump(u,step))
res+=a[u];
printf("%d\n",res);
}
return 0;
}

  

bzoj4381: [POI2015]Odwiedziny的更多相关文章

  1. BZOJ4381[POI2015]Odwiedziny——分块+长链剖分

    题目描述 给定一棵n个点的树,树上每条边的长度都为1,第i个点的权值为a[i].Byteasar想要走遍这整棵树,他会按照某个1到n的全排列b走n-1次,第i次他会从b[i]点走到b[i+1]点,并且 ...

  2. BZOJ4381 : [POI2015]Odwiedziny / Luogu3591[POI2015]ODW - 分块+树剖

    Solution 在步伐$pace$比较小的时候, 我们发现用前缀和直接维护会很快 而在$pace$比较大的时候, 则暴力往上跳会最优 设$blo= \sqrt{N}$ 若$pace<=blo$ ...

  3. [POI2015]Odwiedziny

    [POI2015]Odwiedziny 题目大意: 一棵\(n(n\le5\times10^4)\)个点的树,\(n\)次询问从一个点到另一个点的路径上,每次跳\(k\)个点,所经过的点权和. 思路: ...

  4. @bzoj - 4381@ [POI2015] Odwiedziny

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一棵 n 个点的树,树上每条边的长度都为 1 ,第 i 个点 ...

  5. POI2015题解

    POI2015题解 吐槽一下为什么POI2015开始就成了破烂波兰文题目名了啊... 咕了一道3748没写打表题没什么意思,还剩\(BZOJ\)上的\(14\)道题. [BZOJ3746][POI20 ...

  6. [Poi2015]

    [POI2015]Łasuchy 一看以为是sb题 简单来说就是每个人获得热量要尽量多 不能找别人 首先这道题好像我自己找不到NIE的情况 很容易想到一个优化 如果一个数/2>另一个数 那么一定 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. poi2015 bzoj4377-4386训练

    就按时间顺序写吧 完成度:10/10 3.30 bzoj4385 首先一定是删去连续d个数,然后枚举终点,起点显然有单调性,用单调队列乱搞搞就可以啦 bzoj4378 首先才结论:可行当且仅当把所有大 ...

  9. BZOJ 4385: [POI2015]Wilcze doły

    4385: [POI2015]Wilcze doły Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 648  Solved: 263[Submit][ ...

随机推荐

  1. TextView和EditText中的setFilters方法说明

    在TextView中有一个方法public void setFilters(InputFilter[] filters),API中有一句说明:Sets the list of input filter ...

  2. android gridview画分割线,如图:

    1.先上图: 2.具体实现代码: public class LineGridView extends GridView { public LineGridView(Context context) { ...

  3. 源码安装mysql

    1. 安装依赖组件 # yum install gcc gcc-c++ ncurses-devel perl -y   2. 安装cmake # wget http://www.cmake.org/f ...

  4. .net AES加密解密

    using System;      using System.Collections.Generic;      using System.Text;      using System.Secur ...

  5. BZOJ 1251: 序列终结者

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 3773  Solved: 1579 [Submit][Status][Dis ...

  6. KeyBord事件从Activtiy层往下分发详细过程代码示例

    step1:调用Activity成员函数dispatchKeyEvent public boolean dispatchKeyEvent(KeyEvent event) { // Let action ...

  7. linux addr2line 定位so库崩溃位置

    在Linux下写C/C++程序的程序员,时常与Core Dump相见.在内存越界访问,收到不能处理的信号,除零等错误出现时,我们精心或不精心写就的程序就直接一命呜呼了,Core Dump是Linux仁 ...

  8. 20145221 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验

    20145221 <信息安全系统设计基础>实验五 简单嵌入式WEB服务器实验 实验报告 队友博客:20145326蔡馨熠 实验博客:<信息安全系统设计基础>实验五 简单嵌入式W ...

  9. GBPR: Group Preference Based Bayesian Personalized Ranking for One-Class Collaborative Filtering-IJACA 2013_20160421

    1.Information publication:IJACA 2013 2.What 基于BPR模型的改进:改变BPR模型中,a,用户对商品喜好偏序对之间相互独立;b,用户之间相互独立的假设 原因: ...

  10. JavaScript学习笔记- 正则表达式常用验证

    <div> <h1>一.判断中国邮政编码匹配</h1> <p>分析:中国邮政编码都是6位,且为纯数字</p> <div>邮政编码 ...