HDU - 5571 :tree (动态点分治 异或)
题意:给定一棵树,有点权a[],有边权。 现在有M次修改点权的操作,输出每次修改后,Σ(a[i]^a[j])*dis(i,j);
思路:因为待修改,我们需要快速得到以及修改一个点到其他所有点的信息。 肯定就是动态点分治了啊。
而异或这个操作没有什么累加的性质,所以每一位拆开单独计算。 根据二进制位置和01区别,先建立14*2点分树。然后每次在同一位置,不同值的树上累加答案。
因为计算dis的过程会重复很多次,所以可以用个dd数组,减少重复统计,然后就用1400ms变成 了960ms。
#include<bits/stdc++.h>
#define FOR() for(int i=Laxt[u];i;i=Next[i])
#define ll long long
#define rep(i,w,v) for(int i=w;i<=v;i++)
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn<<],To[maxn<<],Len[maxn<<],cnt;
int a[maxn],sz[maxn],son[maxn],dep[maxn];
int Top[maxn],fa[maxn],Fa[maxn],vis[maxn],root,SZ;
ll G[maxn][][],F[maxn][][],ans,dis[maxn]; //
int num[maxn][][],mx;
void init(int N)
{
cnt=; rep(i,,N) Laxt[i]=;
rep(i,,N) vis[i]=; ans=;
rep(i,,N) rep(j,,) rep(k,,)
G[i][j][k]=F[i][j][k]=num[i][j][k]=;
}
void add(int u,int v,int len)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=len;
}
void dfs1(int u,int f)
{
sz[u]=; dep[u]=dep[f]+; fa[u]=f; son[u]=;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i]; if(v==f) continue;
dis[v]=dis[u]+Len[i];
dfs1(v,u); sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
void dfs2(int u,int tp)
{
Top[u]=tp;
if(son[u]) dfs2(son[u],tp);
FOR()
if(To[i]!=fa[u]&&To[i]!=son[u])
dfs2(To[i],To[i]);
} int LCA(int u,int v)
{
while(Top[u]^Top[v]) dep[Top[u]]<dep[Top[v]]?v=fa[Top[v]]:u=fa[Top[u]];
return dep[u]<dep[v]?u:v;
}
ll getdis(int u,int v){return dis[u]+dis[v]-*dis[LCA(u,v)];}
void Getroot(int u,int ff)
{
sz[u]=;int ret=;
FOR(){
int v=To[i];if(v==ff||vis[v])continue;
Getroot(v,u);sz[u]+=sz[v];
ret=max(ret,sz[v]);
}
ret=max(ret,SZ-sz[u]);
if(ret<mx) mx=ret,root=u;
}
void DFS(int u,int ff)
{
vis[u]=true; Fa[u]=ff;
FOR(){
int v=To[i];if(vis[v])continue;
mx=SZ=sz[v];
Getroot(v,u);
DFS(root,u);
}
}
ll dd[maxn];
void Modify(int u,int val,int opt)
{
int t;
for(int j=u;Fa[j];j=Fa[j]) dd[j]=getdis(u,Fa[j]);
rep(i,,){
if(val&(<<i)) t=;
else t=;
ans=ans+1LL*opt*(<<i)*G[u][i][t^];
for(int j=u;Fa[j];j=Fa[j]){
ll d=dd[j];
ans=ans+1LL*opt*(<<i)*(1LL*d*(num[Fa[j]][i][t^]-num[j][i][t^])+G[Fa[j]][i][t^]-F[j][i][t^]);
}
}
rep(i,,){
if(val&(<<i)) t=;
else t=;
num[u][i][t]+=opt;
for(int j=u;Fa[j];j=Fa[j]){
ll d=dd[j];
G[Fa[j]][i][t]+=d*opt;
F[j][i][t]+=d*opt;
num[Fa[j]][i][t]+=opt;
}
}
}
int main()
{
int N,Q,D,E,u,v,l;
while(~scanf("%d",&N)){
init(N);
rep(i,,N) scanf("%d",&a[i]);
rep(i,,N-){
scanf("%d%d%d",&u,&v,&l);
add(u,v,l); add(v,u,l);
}
dfs1(,); dfs2(,);
SZ=mx=N; Getroot(,);
DFS(root,);
rep(i,,N) Modify(i,a[i],);
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&D,&E);
Modify(D,a[D],-);
a[D]=E;
Modify(D,a[D],);
printf("%lld\n",ans);
}
}
return ;
}
HDU - 5571 :tree (动态点分治 异或)的更多相关文章
- hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...
- hdu 5909 Tree Cutting —— 点分治
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治,每次的 rt 是必选的点: 考虑必须选根的一个连通块,可以DP,决策就是在每个子树中决定选不 ...
- hdu 4670 Cube number on a tree(点分治)
Cube number on a tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/ ...
- HDU 4918 Query on the subtree(动态点分治+树状数组)
题意 给定一棵 \(n\) 个节点的树,每个节点有点权.完成 \(q\) 个操作--操作分两种:修改点 \(x\) 的点权.查询与 \(x\) 距离小于等于 \(d\) 的权值总和. \(1 \leq ...
- 【BZOJ-3730】震波 动态点分治 + 树状数组
3730: 震波 Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 626 Solved: 149[Submit][Status][Discuss] D ...
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
- BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
- 点分治&动态点分治小结
(写篇博客证明自己还活着×2) 转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8006488.html 有的时候,我们会发现这样一类题:它长得很像一个$O(n) ...
- 点分治&&动态点分治学习笔记
突然发现网上关于点分和动态点分的教程好像很少……蒟蒻开篇blog记录一下吧……因为这是个大傻逼,可能有很多地方写错,欢迎在下面提出 参考文献:https://www.cnblogs.com/LadyL ...
随机推荐
- scala 类,伴生对象
1.属性的定义 编写一个PersonS类,并在其中定义一些属性,通过PersonS.scala 编译后的情况查看,可以知道不同修饰符修饰的属性分别会生成什么方法(set,get) package co ...
- 小甲鱼汇编语言学习笔记——day02
1.8086CPU不支持将数据直接送入段寄存器,需要按照下面方式:数据——>通用寄存器——>段寄存器. 2.mov指令的几种形式: mov 寄存器,数据 mov 寄存器,寄存器 mov 寄 ...
- PostgreSQL 参数调整(性能优化)
昨天分别在外网和无外网环境下安装PostgreSQL,有外网环境下安装的相当顺利.但是在无外网环境下就是两个不同的概念了,可谓十有八折.感兴趣的同学可以搭建一下. PostgreSQL安装完成后第一件 ...
- Python知识点总结篇(三)
文件操作 对文件操作流程 打开文件,得到文件句柄并赋值给一个变量: 通过句柄对文件进行操作: 关闭文件: with:自动关闭文件: with open('log', 'r') as f: ... 文件 ...
- golang开发:环境篇(六) Go运行监控Supervisord的使用
为什么要使用Supervisord 17年第一次写Go项目的时候,用Go开发项目倒没没费多大劲,很快就开发完成了.到了在测试环境部署的时候,由于不知道有 Supervisord 这个软件,着实花了些功 ...
- 【实战经验】Xilinx时钟从普通IO输出问题
Xilinx芯片的时钟信号从普通IO输出时,在map过程中会出错,对此有两种解决方案: 1.在ucf文件中,添加对应的约束文件: 例如[PIN "U0_1/clkout2_buf.O&quo ...
- Glances - Linux上的实时系统监控工具(Centos安装)
Glances WebServer 模式 在 glances 的 WebServer 模式下,客户端只通过浏览器访问就可以获取远程服务器的运行状态. 安装成功后,使用 glances -w 命令即可 ...
- PHP获取前台传过来的时间年份,进行处理。
在做时间区间用到一个方法,以方便在数据库中用in()的使用,这个是我同事给我的,我先保存好,以后还可以的用到. /*处理起终年月,返回中间的月份以供数据库查询使用 * @param $yearl 起始 ...
- 两个div并排显示,当浏览器界面缩小时会出现换行
解决:规定两个子div的父div的宽 <div id="showDataDiv" style="width: 1000px"> <div st ...
- java之 代理设计模式
1. 设计一个案例来实现租房功能.分析:在租房的过程中涉及到了3个对象,房东,中介,房客. 中介和房客具有相同的功能--租房. 可以设计如下: 2.上图的设计实际上就是一个代理设计模式---静态代理设 ...