题目链接: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(树的分治+树状数组)的更多相关文章

  1. CF 293 E Close Vertices (树的分治+树状数组)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题目:给出一棵树,问有多少条路径权值和不大于w,长 ...

  2. 【bzoj3648】环套树+点分治+树状数组

    tree 1s 128M  by hzw czy神犇种了一棵树,他想知道地球的质量 给定一棵n个点的树,求树上经过点的个数≥K的路径数量ans 对于部分数据,树上某两点间会多出最多一条无向边 输入数据 ...

  3. [bzoj3155]Preprefix sum(树状数组)

    3155: Preprefix sum Time Limit: 1 Sec  Memory Limit: 512 MBSubmit: 1183  Solved: 546[Submit][Status] ...

  4. Codeforces 980E The Number Games - 贪心 - 树状数组

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗有$n$个点的树,$i$号点的权值是$2^{i}$要求删去$k$个点,使得剩下的点仍然连通,并且总权值和最大,问删去的所有点的编号. ...

  5. HDU 4918 Query on the subtree(动态点分治+树状数组)

    题意 给定一棵 \(n\) 个节点的树,每个节点有点权.完成 \(q\) 个操作--操作分两种:修改点 \(x\) 的点权.查询与 \(x\) 距离小于等于 \(d\) 的权值总和. \(1 \leq ...

  6. 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 ...

  7. bzoj3648: 寝室管理(环套树+点分治)

    好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...

  8. 【BZOJ-3648】寝室管理 环套树 + 树状数组 + 点分治

    3648: 寝室管理 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 239  Solved: 106[Submit][Status][Discuss] ...

  9. 【Bzoj 3295】 动态逆序对(树套树|CDQ分治)

    [题意] 每次删除一个数,然后问删除前逆序对数. [分析] 没有AC不开心.. 我的树状数组套字母树,应该是爆空间的,空间复杂度O(nlogn^2)啊..哭.. 然后就没有然后了,别人家的树套树是树状 ...

随机推荐

  1. 关于在框架中使用curl的思考,以及,curl其实很好用

    初步猜想: 在接触到框架文档的第一阶段时,会觉得控制器调用模型就是一件很简单的事,tp中用D方法或者M方法来实例化模型,laravel中用命名空间来加载模型,CI中用$this->load-&g ...

  2. jvm的垃圾回收几种理解

    1.引用计数器回收 给每个对象设置一个计数器,当该对象被引用时,计数器加1,当有其他变量不再引用该对象时,计数器减1.直到计数器数值为0,回收器视为他是‘垃圾’,可以被回收,当该对象被回收时,其他引用 ...

  3. Tiny6410之NAND FLASH驱动

    一.NAND FLASH的特点 S3C6410的NAND FLASH控制器有如下特点 1.自导入模式:复位后,引导代码被送入到8KB的STEPPINGSTONE中,引导代码移动完毕,引导代码将在STE ...

  4. maven中在本地maven仓库添加jar包

    Maven 手动添加 JAR 包到本地仓库 Maven 确确实实是个好东西,用来管理项目显得很方便,但是如果是通过 Maven 来远程下载 JAR 包的话,我宿舍的带宽是4兆的,4个人共用,有时候用  ...

  5. div显示与隐藏及height()函数

    总结与网络 1. $("#id").show()表示display:block,$("#id").hide()表示display:none; $("# ...

  6. 阿里云ECS-Nginx阿里云客户端IP日志记录

    #前端有SLB服务,记录客户端真实IP信息 log_format main 'realip:$http_x_forwarded_for slbip:$remote_addr-$remote_user ...

  7. EF OrderBy(string propertyname), OrderByDescending(string propertyname) 按属性排序,扩展方法

    public static class LinqExtensions { private static PropertyInfo GetPropertyInfo(Type objType, strin ...

  8. Java语法基础总结

    这次上课我们讲了Java语言中的枚举类型,并进行了一次课堂测试,测试代码如下: public class EnumTest { public static void main(String[] arg ...

  9. 实战荟萃-UI篇

    一. 前言 平时在处理问题的时候,经常会遇到一些奇奇怪怪的问题,今天在这里将其记录下来.这里将会列举几个常用的UI问题进行讲解 二. 导航栏 iOS导航栏绝对是个巨坑.和很多朋友聊天都是自己实现了一套 ...

  10. js实现的笛卡尔乘积-商品发布

    //笛卡儿积组合 function descartes(list) { //parent上一级索引;count指针计数 var point = {}; var result = []; var pIn ...