hdu_4918_Query on the subtree(树的分治+树状数组)
题目链接:hdu_4918_Query on the subtree
题意:
给出一颗n个点的树,每个点有一个权值,有两种操作,一种是将某个点的权值修改为v,另一种是查询距离点u不超过d的点的权值和。
题解:
这里可以去膜膜鸟神的博客。
简单来说就是对树的每个重心建立两个树状数组,然后对于每个点修改就在每个重心的BIT中去修改,查询也在每个重心的BIT中查询,然后容斥一下,就得出答案。
每种操作的复杂度为log2n,这题的细节比较多,具体看代码。
#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define pb push_back
using namespace std;
const int N=1e5+; int n,q,g[N],nxt[N*],v[N*],ed,w[N],vis[N],id[N];
int pool[*N],C_ed,pool_ed,sz[N],mi,mx[N],ROOT;
char op[]; struct node
{
int rt,subrt,dis;
node(){}
node(int _rt,int _subrt,int _dis):rt(_rt),subrt(_subrt),dis(_dis){}
}tmp;
vector<node>vt[N]; void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
void init(){ed=C_ed=pool_ed=;F(i,,n)vt[i].clear(),vis[i]=g[i]=;}
inline void up(int &a,int b){if(a<b)a=b;} struct BIT
{
int *C,n;
void init(int tot){n=tot,C=pool+pool_ed,pool_ed+=tot+;F(i,,n)C[i]=;}
inline void add(int x,int c){while(x<=n)C[x]+=c,x+=x&-x;}
inline int ask(int x,int an=)
{
if(x>n)x=n;
while(x>)an+=C[x],x-=x&-x;
return an;
}
}tr[N*]; void get_rt(int u,int fa,int num)
{
sz[u]=,mx[u]=;
for(int i=g[u];i;i=nxt[i])
if(!vis[v[i]]&&v[i]!=fa)
{
get_rt(v[i],u,num);
sz[u]+=sz[v[i]],up(mx[u],sz[v[i]]);
}
up(mx[u],num-sz[u]);
if(mx[u]<mi)ROOT=u,mi=mx[u];
} void del(int u,int fa,int rt,int subrt,int dis=)//将子树的每个点放进对应的重心
{
vt[u].pb(node(rt,subrt,dis));
tr[rt].add(dis+,w[u]);
tr[subrt].add(dis+,w[u]);
for(int i=g[u];i;i=nxt[i])
if(v[i]!=fa&&!vis[v[i]])
del(v[i],u,rt,subrt,dis+);
} void init_tree(int u=,int num=n)
{
mi=N,get_rt(u,u,num);
int rt=ROOT,rt_id=++C_ed;
tr[C_ed].init(sz[u]+);
vis[rt]=,vt[rt].pb(node(C_ed,,));
tr[C_ed].add(,w[rt]);
get_rt(rt,rt,num);//从新计算sz的大小
for(int i=g[rt];i;i=nxt[i])
if(!vis[v[i]])
{
tr[++C_ed].init(sz[v[i]]+);
del(v[i],v[i],rt_id,C_ed);
}
for(int i=g[rt];i;i=nxt[i])
if(!vis[v[i]])
init_tree(v[i],sz[v[i]]);
} int main()
{
while(~scanf("%d%d",&n,&q))
{
init();
F(i,,n)scanf("%d",w+i);
F(i,,n-)
{
int x,y;
scanf("%d%d",&x,&y);
adg(x,y),adg(y,x);
}
init_tree();
while(q--)
{
int u,v;
scanf("%s%d%d",op,&u,&v);
if(op[]=='!')
{
int size=vt[u].size(),d=v-w[u];
F(i,,size-)
{
tmp=vt[u][i];
tr[tmp.rt].add(tmp.dis+,d);//dis+1去掉距离为0在BIT上超时的BUG
if(tmp.subrt)tr[tmp.subrt].add(tmp.dis+,d);
}
w[u]+=d;
}else
{
int d=v,ans=,size=vt[u].size();
F(i,,size-)
{
tmp=vt[u][i];
ans+=tr[tmp.rt].ask(d-tmp.dis+);
if(tmp.subrt)ans-=tr[tmp.subrt].ask(d-tmp.dis+);
}
printf("%d\n",ans);
}
}
}
return ;
}
hdu_4918_Query on the subtree(树的分治+树状数组)的更多相关文章
- CF 293 E Close Vertices (树的分治+树状数组)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题目:给出一棵树,问有多少条路径权值和不大于w,长 ...
- 【bzoj3648】环套树+点分治+树状数组
tree 1s 128M by hzw czy神犇种了一棵树,他想知道地球的质量 给定一棵n个点的树,求树上经过点的个数≥K的路径数量ans 对于部分数据,树上某两点间会多出最多一条无向边 输入数据 ...
- [bzoj3155]Preprefix sum(树状数组)
3155: Preprefix sum Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 1183 Solved: 546[Submit][Status] ...
- Codeforces 980E The Number Games - 贪心 - 树状数组
题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗有$n$个点的树,$i$号点的权值是$2^{i}$要求删去$k$个点,使得剩下的点仍然连通,并且总权值和最大,问删去的所有点的编号. ...
- HDU 4918 Query on the subtree(动态点分治+树状数组)
题意 给定一棵 \(n\) 个节点的树,每个节点有点权.完成 \(q\) 个操作--操作分两种:修改点 \(x\) 的点权.查询与 \(x\) 距离小于等于 \(d\) 的权值总和. \(1 \leq ...
- HDU4918 Query on the subtree 点分治+树状数组
bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n. At the very begining, the i-th ...
- bzoj3648: 寝室管理(环套树+点分治)
好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...
- 【BZOJ-3648】寝室管理 环套树 + 树状数组 + 点分治
3648: 寝室管理 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 239 Solved: 106[Submit][Status][Discuss] ...
- 【Bzoj 3295】 动态逆序对(树套树|CDQ分治)
[题意] 每次删除一个数,然后问删除前逆序对数. [分析] 没有AC不开心.. 我的树状数组套字母树,应该是爆空间的,空间复杂度O(nlogn^2)啊..哭.. 然后就没有然后了,别人家的树套树是树状 ...
随机推荐
- 【1】Hover 效果收集
各种 hover 效果 github repository>> git 仓库 1. 背景图的 hover 效果 原页面>> githubSite>>
- 如何通过fpmmm和zabbix来监控客户机上MariaDB数据库运行情况
首先在客户机安装MariaDB和zabbix,参考上一篇 安装fpmmm的过程主要参考[1]. 安装fpmmm的依赖 shell> yum install php-cli php-process ...
- CoreJavaE10V1P3.6 第3章 Java的基本编程结构-3.6 字符串 String
String类(java.lang.String)就是Unicode字符序列,例如:"Java\u2122" 3.6.1 Substring 提取子串 String greetin ...
- FTP上传下载工具(FlashFXP) v5.5.0 中文版
软件名称: FTP上传下载工具(FlashFXP) 软件语言: 简体中文 授权方式: 免费试用 运行环境: Win 32位/64位 软件大小: 7.4MB 图片预览: 软件简介: FlashFXP 是 ...
- 利用css来让一个div在页面中垂直居中的方法
一.如何让一个div在页面中垂直居中(请至少列出三种) 1.距离页面窗口左边框和上边框的距离设置为50%,这个50%就是指页面窗口的宽度和高度的50%,最后将该DIV分别左移和上移,左移和上移的大小就 ...
- 浙大 pat 1038 题解
1038. Recover the Smallest Number (30) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHE ...
- js便利关联数组 及数组定义方式 分类
"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv=& ...
- Ubuntu 忘记密码
1重启电脑Shift键进入GRUB引导模式如下图所示,选择第二行的recovery mode. 2 安e进入recovery mode 编译kernel进行启动参数 3 在linux /boot/vm ...
- linux下获取硬盘、内存、U盘大小及使用大小
/* * 获取硬盘大小;内存大小;usb大小 */ #ifndef SYSINFOGET_H #define SYSINFOGET_H #include <stdio.h> //磁盘信息 ...
- 使用SyncToy 同步两台机器上的文件夹
@echo off echo 准备启动同步... net use \\WIN-AJH8QENQQGK "123456" /user:Administrator Z:\SyncToy ...