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 ...
随机推荐
- Oracle Spatial分区应用研究之七:同等分区粒度下全局索引优于分区索引的原因分析
1.实验结论 同等分区粒度下,使用分区空间索引进行空间查询,比使用全局空间索引进行查询,对数据字典表的访问次数更多.假设分区数为X,则大概多3X次访问.具体说明见6实验结论. 2.实验目的 在之前的测 ...
- PHP写接口需要注意的问题
PHP写接口需要注意的问题方法前面建议写传过来的参数 1 防止xss攻击2 防止sql语句注入3 sign签名验证4 不经常更新的加索引和缓存 app请求时候 参数都要加urlencode 防止参数带 ...
- 025 SSM综合练习01--数据后台管理系统--功能介绍及数据库表
1.功能介绍 (1)环境搭建 主要讲解maven工程搭建,以及基于oracle数据库的商品表信息,并完成SSM整合.(2)商品查询 基于SSM整合基础上完成商品查询,要掌握主面页面main.jsp及商 ...
- Flume和 Sqoop
Sqoop简介 Sqoop是一种旨在有效地在Apache Hadoop和诸如关系数据库等结构化数据存储之间传输大量数据的工具 原理: 将导入或导出命令翻译成Mapreduce程序来实现. 在翻译出的M ...
- JSON学习(一)
JSON: 1. 概念: JavaScript Object Notation JavaScript对象表示法 Person p = new Person(); p.setName(" ...
- python学习-32 zip函数
zip 拉链方法 例如:1. ')))) 运行结果: [(')] Process finished with exit code 0 2. a = {'name':'abc','age':18,'ad ...
- day08——文件操作
day08 文件操作: open() :打开 f (文件句柄)= open("文件的路径(文件放的位置)",mode="操作文件的模式",encoding=&q ...
- Windows状态栏图标显示异常
1.新建TXT文档 2.写上以下代码 taskkill /im explorer.exe /f cd /d %userprofile%\appdata\local del iconcache.db / ...
- 了解下Scala隐式转换与柯理化
之前有看过kafka源码,有很多implict声明的方法,当时看的一头雾水,今天趁着空闲,了解下scala 的隐式转换和柯理化相关语法知识. 隐式转换 需要类中的一个方法,但是这个类没有提供这样的一个 ...
- java基础 Arrays
package cn.mantishell.day08.demo04; import java.util.Arrays; /** * java.util.Arrays是一个与数组相关的工具类,里面提供 ...