[SimpleOJ238]宝藏探寻
题目大意:
给你一棵带点权的n个结点的树,有m次询问,每次从树上删掉一条路径(u,v),问删掉每条路径后各个连通块权值和的平方之和。
每次询问是独立的。
思路:
首先对树遍历一遍求出每棵子树的权值和。
然后倍增记录下每个结点往上跳2^k层,深度范围内与这条路径无关的每个连通块的权值和的平方之和。
然后询问的时候直接倍增往上跳即可,注意跳最后一层的时候要特判一下。
#include<cstdio>
#include<cctype>
#include<vector>
typedef long long int64;
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=;
int w[N],sum[N],par[N],dep[N];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
void dfs(const int &x,const int &p) {
par[x]=p;
dep[x]=dep[p]+;
sum[x]=w[x];
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==p) continue;
dfs(y,x);
sum[x]+=sum[y];
}
}
inline int64 sqr(const int64 &x) {
return x*x;
}
inline int lca(int x,int y) {
while(x!=y) {
if(dep[x]<dep[y]) std::swap(x,y);
x=par[x];
}
return x;
}
inline int64 solve(int x,int y) {
int64 ans=;
if(x==y) {
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par[x]) continue;
ans+=sqr(sum[y]);
}
ans+=sqr(sum[]-sum[x]);
return ans;
}
if(x!=lca(x,y)) {
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par[x]) continue;
ans+=sqr(sum[y]);
}
}
std::swap(x,y);
if(x!=lca(x,y)) {
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par[x]) continue;
ans+=sqr(sum[y]);
}
}
while(par[x]!=par[y]&&x!=y) {
if(dep[x]<dep[y]) std::swap(x,y);
for(register unsigned i=;i<e[par[x]].size();i++) {
const int &y=e[par[x]][i];
if(y==par[par[x]]||y==x) continue;
ans+=sqr(sum[y]);
}
x=par[x];
}
if(x!=y) {
for(register unsigned i=;i<e[par[x]].size();i++) {
const int &to=e[par[x]][i];
if(to==par[par[x]]||to==x||to==y) continue;
ans+=sqr(sum[to]);
}
x=par[x];
}
ans+=sqr(sum[]-sum[x]);
return ans;
}
int top;
void dfs1(const int &x,const int &par) {
top=x;
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs1(y,x);
}
}
int sum2[N];
void dfs2(const int &x,const int &par) {
sum2[x]=sum[par]+w[par];
dep[x]=dep[par]+;
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs2(y,x);
sum[x]=sum[y]+w[y];
}
}
int main() {
int n=getint(),m=getint();
for(register int i=;i<=n;i++) {
w[i]=getint();
}
for(register int i=;i<n;i++) {
add_edge(getint(),getint());
}
if(n%==) {
dfs1(,);
dfs2(top,);
while(m--) {
int x=getint(),y=getint();
if(dep[x]<dep[y]) std::swap(x,y);
printf("%lld\n",sqr(sum[x])+sqr(sum2[y]));
}
return ;
}
dfs(,);
while(m--) {
printf("%lld\n",solve(getint(),getint()));
}
return ;
}
[SimpleOJ238]宝藏探寻的更多相关文章
- nyoj 探寻宝藏
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处 ...
- 探寻宝藏(双向DP)
题目描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角.当然,迷宫中的通路不是平坦 ...
- NYOJ-712 探寻宝藏(第六届河南省程序设计大赛)
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫 ...
- ny712 探寻宝藏 ny61 传纸条(1)
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处 ...
- 探寻宝藏 --- 双线DP
双线DP , 在郑轻的时候 做过 这种双线DP , 这是多维DP 应该是比较简单的 但是那个 时间复杂度的优化 始终看不懂 . 先附上代码吧 , 等看懂了再来 , 补充一下 解释 . #in ...
- 探寻 JavaScript 逻辑运算符(与、或)的真谛
十二月已经过半,冬季是一个美妙的季节,寒冷的空气逼得人们不得不躲在安逸舒适的环境里生活.冬季会给人一种安静祥和的氛围,让人沉浸在其中,仿佛是一个旧的阶段的结束,同时也是一个新的阶段的开始.这么说来,西 ...
- 算法:poj1066 宝藏猎人问题。
package practice; import java.util.Scanner; public class TreasureHunt { public static void main(Stri ...
- 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 787 Solved: 318[Submit][Stat ...
- zzulioj 1907小火山的宝藏交易(dfs记忆化搜索)
#include <stdio.h> #include <algorithm> #include <string.h> #include <vector> ...
随机推荐
- CodeForces - 996B
Allen wants to enter a fan zone that occupies a round square and has nn entrances. There already is ...
- 从INT_MAX和INT_MIN看补码
刷一道题的时候遇到INT_MAX和INT_MIN的问题,有些东西忘了,梳理一下. INT_MAX为2147483647,INT_MIN为-2147483648,为什么MIN的绝对值比MAX多1呢,因为 ...
- Sublime删除项目删不掉?
最近用sublime进行项目的开发,感觉懵逼的像个小白菜~~ 今天遇到的问题可是一个超级白痴的问题,sublime的空白项目文件夹怎么都删不掉,我的傻逼操作是:选中文件--->Delete--- ...
- spring-boot-资源处理
WebMvcConfigurerAdapter 使用 1.实现 HandlerInterceptorAdapter 2.添加拦截器 重写WebMvcConfigurerAdapter中的addInte ...
- SSO单点登录的发展由来以及实现原理【转】
单点登录以及权限,在很早之前都有写过,不过都比较简单,今天就具体说一下,以及下一步要做的 1.web单系统应用 早期我们开发web应用都是所有的包放在一起打成一个war包放入tomcat容器来运行的, ...
- Java Web 远程调试
Java Web 远程 调试 Tomcat 下载压缩版服务器 环境:Tomcat.Eclipse,做远程调试我们并不需要其他特殊插件 1.配置Tomcat/bin/startup.bat 在前面增加代 ...
- <mvc:annotation-driven/>都做了那些事情
mvc:annotation-driven是一种简写的配置方式,那么mvc:annotation-driven到底做了哪些工作呢?如何替换掉mvc:annotation-driven呢? <mv ...
- Android检测富文本中的<img标签并实现点击效果
本文旨在:通过点击一张图片Toast输出位置与url链接. 闲话少说,实现原理大概是酱紫的::通过正则表达式检测富文本内的图片集合并获取url,在src=“xxx” 后面添加 onclick方法,至于 ...
- leetcode 之Remove Duplicates from Sorted Array(1)
删除数组中的重复元素并返回新数组的个数 思路:保留不同的元素即可. int removeDeplicates(int A[], int n) { ; ; i < n; i++) { if (A[ ...
- pandas 数据结构的基本功能
操作Series和DataFrame中的数据的常用方法: 导入python库: import numpy as np import pandas as pd 测试的数据结构: Series: > ...