题意:给定一棵树,有点权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 (动态点分治 异或)的更多相关文章

  1. hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...

  2. hdu 5909 Tree Cutting —— 点分治

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治,每次的 rt 是必选的点: 考虑必须选根的一个连通块,可以DP,决策就是在每个子树中决定选不 ...

  3. 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/ ...

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

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

  5. 【BZOJ-3730】震波 动态点分治 + 树状数组

    3730: 震波 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 626  Solved: 149[Submit][Status][Discuss] D ...

  6. hdu 5909 Tree Cutting [树形DP fwt]

    hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...

  7. BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)

    题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...

  8. 点分治&动态点分治小结

    (写篇博客证明自己还活着×2) 转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8006488.html 有的时候,我们会发现这样一类题:它长得很像一个$O(n) ...

  9. 点分治&&动态点分治学习笔记

    突然发现网上关于点分和动态点分的教程好像很少……蒟蒻开篇blog记录一下吧……因为这是个大傻逼,可能有很多地方写错,欢迎在下面提出 参考文献:https://www.cnblogs.com/LadyL ...

随机推荐

  1. CentOS 5 源

    # The mirror system uses the connecting IP address of the client and the # update status of each mir ...

  2. 如何使用RedisTemplate访问Redis数据结构之Zset

    Redis的ZSet数据结构 Redis 有序集合和无序集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合 ...

  3. count_if 功能模板

    count_if 功能模板 template <class InputIterator, class UnaryPredicate> typename iterator_traits< ...

  4. (转)数据库_不懂数据库索引的底层原理?那是因为你心里没点BTree

    原文地址:https://www.cnblogs.com/sujing/p/11110292.html 要了解数据库索引的底层原理,我们就得先了解一种叫树的数据结构,而树中很经典的一种数据结构就是二叉 ...

  5. IIS err_connection_timed_out(响应时间过长)

    场景:我在服务器的IIS上部署了一个网站,服务器上可以正常打开,然后我用自己的电脑访问,出现如下错误: 原因:服务器的防火墙对入站规则进行了一些限制. 解决方法:1.打开服务器的防火墙-----> ...

  6. Parameter 0 of method sqlSessionTemplate in org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration required a single bean, but 2 were found:

    Parameter 0 of method orderSqlSessionFactory in com.config.MultipleDBConfig required a single bean, ...

  7. 在Linux系统中创建SSH服务器别名

    如果你经常通过 SSH 访问许多不同的远程系统,这个技巧将为你节省一些时间.你可以通过 SSH 为频繁访问的系统创建 SSH 别名,这样你就不必记住所有不同的用户名.主机名.SSH 端口号和 IP 地 ...

  8. pandas-15 df['one_col'].apply()方法的用法

    pandas-15 df['one_col'].apply()方法的用法 apply有点像map的用法,可以传入一个函数. 如:df['A'].apply(str.upper) import nump ...

  9. ASP.Net超时时间已到解决办法-

    解决办法 1.在代码里面,把未关闭的连接关闭 2.扩大共享池,方法如下: 解决方法可以是修改连接池的连接生存期,因为默认值是60秒,即连接从应用程序被释放后可以在池中保存的时间. 具体操作步骤如下: ...

  10. 【转载】C#中double.TryParse方法和double.Parse方法的异同之处

    在C#编程过程中,double.TryParse方法和double.Parse方法都可以将字符串string转换为double类型,但两者还是有区别,最重要的区别在于double.TryParse方法 ...