BZOJ3730 震波 | 动态点分治
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 100005, INF = 0x3f3f3f3f;
int n, m, ans;
int ecnt, adj[N], nxt[2*N], go[2*N];
int val[N], fa[N][20], dis[N][20], dep[N], sze[N], son[N], rt, sz;
bool vis[N];
vector <int> bit[N], fbit[N];
/* 变量解释:
fa[i][j] : 第j次分治中, i所属的连通块的重心
dis[i][j] : i到fa[i][j]的距离
dep[i] : 点分树上i的深度
sze, son, rt, sz 用于求重心
vis 用于点分治标注
bit[i] : 当i为重心时, 能求"离i距离为j的点的权值和是多少"的树状数组
fbit[i]: 当fa[i][dep[i] - 1]为重心时, 能求"含i连通块离fa[i][dep[i] - 1]距离为j的点的权值和是多少"的树状数组
*/
void add(int u, int v){
go[++ecnt] = v;
nxt[ecnt] = adj[u];
adj[u] = ecnt;
}
void getG(int u, int pre){
sze[u] = 1, son[u] = 0;
for(int e = adj[u], v; e; e = nxt[e])
if(!vis[v = go[e]] && v != pre){
getG(v, u);
sze[u] += sze[v];
son[u] = max(son[u], sze[v]);
}
son[u] = max(son[u], sz - sze[u]);
if(son[u] < son[rt]) rt = u;
}
void dfs(int u, int pre, int top, int d){
for(int e = adj[u], v; e; e = nxt[e])
if(!vis[v = go[e]] && v != pre){
fa[v][++dep[v]] = top;
dis[v][dep[v]] = d;
dfs(v, u, top, d + 1);
}
}
void build(int u){
vis[u] = 1;
dfs(u, 0, u, 1);
int all = sz;
bit[u].resize(all + 1);
fbit[u].resize(all + 1);
for(int e = adj[u], v; e; e = nxt[e])
if(!vis[v = go[e]]){
sz = sze[v] > sze[u] ? all - sze[u] : sze[v];
rt = 0;
getG(v, u);
build(rt);
}
}
int ask(int u, int k){
int ret = val[u], lim = bit[u].size() - 1;
for(k = min(k, lim); k; k -= k & -k) ret += bit[u][k];
return ret;
}
int fask(int u, int k){
int ret = 0, lim = fbit[u].size() - 1;
for(k = min(k, lim); k; k -= k & -k) ret += fbit[u][k];
return ret;
}
void change(int u, int x){
int lim = bit[u].size() - 1;
for(int j = dis[u][dep[u]]; j <= lim && j; j += j & -j) fbit[u][j] += x;
for(int i = dep[u]; i; i--){
lim = bit[fa[u][i]].size() - 1;
for(int j = dis[u][i]; j <= lim; j += j & -j) bit[fa[u][i]][j] += x;
for(int j = dis[u][i - 1]; j <= lim && j; j += j & -j) fbit[fa[u][i]][j] += x;
}
}
int query(int u, int k){
int ret = ask(u, k);
for(int i = dep[u]; i; i--)
if(dis[u][i] <= k)
ret += ask(fa[u][i], k - dis[u][i]) - fask(fa[u][i + 1], k - dis[u][i]);
return ret;
}
int main(){
read(n), read(m);
for(int i = 1; i <= n; i++) read(val[i]);
for(int i = 1, u, v; i < n; i++)
read(u), read(v), add(u, v), add(v, u);
son[0] = INF, sz = n;
getG(1, 0);
build(rt);
for(int i = 1; i <= n; i++) fa[i][dep[i] + 1] = i;
for(int i = 1; i <= n; i++) change(i, val[i]);
int op, x, y;
while(m--){
read(op), read(x), read(y);
x ^= ans, y ^= ans;
//printf("op = %d, x = %d, y = %d\n", op, x, y);
if(op == 0) write(ans = query(x, y)), enter;
else change(x, y - val[x]), val[x] = y;
}
return 0;
}
BZOJ3730 震波 | 动态点分治的更多相关文章
- bzoj3730 震波 [动态点分治,树状数组]
传送门 思路 如果没有强制在线的话可以离线之后CDQ分治随便搞. 有了强制在线之后--可能可以二维线段树?然而我不会算空间. 然后我们莫名其妙地想到了动态点分治,然后这题就差不多做完了. 点分树有一个 ...
- BZOJ3730震波——动态点分治+线段树(点分树套线段树)
题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...
- bzoj3730 [震波][动态树分治+线段树+LCA]
震波 Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 1573 Solved: 358[Submit][Status][Discuss] Descri ...
- 【BZOJ3730】震波 动态树分治+线段树
[BZOJ3730]震波 Description 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土 ...
- 【BZOJ-3730】震波 动态点分治 + 树状数组
3730: 震波 Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 626 Solved: 149[Submit][Status][Discuss] D ...
- 【bzoj3730】震波 动态点分治+线段树
题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...
- 【BZOJ3730】震波 - 动态点分治
题意: Description 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]. 不幸的是,这片土地常常发生地震, ...
- bzoj 3730: 震波 动态点分治_树链剖分_线段树
##### 题目描述 : 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着 ...
- BZOJ 4372/3370 烁烁的游戏/震波 (动态点分治+线段树)
烁烁的游戏 题目大意: 给你一棵$n$个节点的树,有$m$次操作,询问某个节点的权值,或者将与某个点$x$距离不超过$d$的所有节点的权值都增加$w$ 动态点分裸题 每个节点开一棵权值线段树 对于修改 ...
随机推荐
- ORA-00020:maximum number of processes (150) exceeded
异常的含义 超过最大的进程数 我们使用下面的语句可以查看与进程(process)的相关参数: 如上所示,这里的最大进程数是150. 问题可能存在的原因 1.应用程序在使用数据库连接池时,使用完成后没有 ...
- LOJ #6074. 「2017 山东一轮集训 Day6」子序列
#6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...
- .NET持续集成与自动化部署之路第三篇——测试环境到生产环境的一键部署策略(Windows)
Jenkins测试环境到生产环境的一键部署策略(Windows) 一.前言 前面我们已经初步实现了开发集成环境.测试环境的持续集成(自动化构建.自动化测试.自动化部署).但生产环境自动化部署迟 ...
- python-scapy学习笔记-(1)
主要功能函数sniff sniff(filter="",iface="any",prn=function,count=N) filter参数允许我们对Scapy ...
- SpringMvc执行过程
--Test过程: 1. 先执行各种 Filter 2. HttpServlet.service(ServletRequest req, ServletResponse res) 3. HttpSer ...
- 如何利用Android Studio打包React Native APK
ok!百度出来的东西很杂,所以,这里介绍一种最简单,最合适我们(新手,应该是吧)的APK的打包方式! 当然!这种打包是基于Android Studio的,所以,注意喽!!!! 废话不多说开始吧! 首先 ...
- Scrum Meeting 6
第六次会议 由于之前队员一直在做数据库和编译大作业,课业压力较大,所以软工进度往后拖了好多. No_00:工作情况 No_01:任务说明 待完成 已完成 No_10:燃尽图 N ...
- 《Linux内核设计与实现》 第十八章学习笔记
调 试 一.准备开始 一个bug 一个藏匿bug的内核版本 相关内核代码的知识和运气 知道这个bug最早出现在哪个内核版本中. 1.想要成功进行调试: 让这些错误重现 抽象出问题 从代码中搜索 二. ...
- 软件工程(GZSD2015) 第三次作业提交进度
第三次作业题目请查看这里:软件工程(GZSD2015)第三次作业 开始进入第三次作业提交进度记录中,童鞋们,虚位以待哈... 2015年4月19号 徐镇.尚清丽,C语言 2015年4月21号 毛涛.徐 ...
- const修饰符限定的常量
类型前加const修饰符限定变量为只读,称为常量,定义时必须初始化,且初始化后编译器不允许再修改常量的值. 一.常量的定义 const在类型前面 const int value: //value是co ...