题意

\(n\) 个节点的树,每个点有点权,\(m\) 次操作,操作分两种,修改一个节点的点权,对于一个 \((u,v)\) ,询问 \(\displaystyle\sum_{i=1}^n\sum_{j=1}^n f(i,j)\) 的值,其中如果路径 \((i,j)\) 与路径 \((u,v)\) 有公共点,\(f(i,j)=w_iw_j\)( \(w_i\) 表示节点 \(i\) 的点权),否则 \(f(i,j)=0\) 。

\(1\leq n,m \leq 10^5​\)

思路

先讲一下用 \(\text{LCT}​\) 维护子树信息的写法(以子树和为例)。

我们需要一个两个数组维护和,\(sum,isum\) 前者表示子树和,后者表示虚儿子的和。

\(\text{push_up}\) 函数需要这么写

void push_up(int x){sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+isum[x]+pw[x];}

在连断虚实边时,要注意 \(isum\) 的变化。

void access(int x)
{
for(int y=0;x;y=x,x=fa[x])
splay(x),isum[x]+=-sum[y]+sum[ch[x][1]],ch[x][1]=y,push_up(x);
//其实这里可以不用push_up(x),因为sum值没有变化
}

\(\text{link}\) 函数这样写,因为需要维护子树和,所以两个点直接转到根。

void link(int x,int y)
{
make_root(x),make_root(y);
fa[x]=y;
isum[y]+=sum[x];
push_up(y);
}

\(\text{cut}​\) 函数同理

void cut(int x,int y)
{
make_root(x),access(y),splay(x);
ch[x][1]=fa[y]=0;
push_up(x);
}

正难则反,我们用总的路径 \((i,j)\) 的答案减去没有公共点的路径 \((i,j)\) 的答案。

总的路径非常好求,就是 \(\displaystyle\sum_{i=1}^n\displaystyle\sum_{j=1}^nw_iw_j= (\sum_{i=1}^n w_i)^2​\) 。

为了求没有交点的路径,我们不妨利用 \(\text{LCT}\) 将这条路径的一个端点拎到根,那对与询问 \((u,v)\) ,答案就是这个式子:

\[(\sum_{i=1}^n w_i)^2-\sum_{p\in \text{Path}(u,v)} \sum_{q\in \text{son}(p)\text{且}q\not\in{\text{Path}(u,v)}}sum_q^2
\]

其中 \(sum_i\) 表示子树和,我们需要用上面的方法去维护它。不难发现,实化路径 \((u,v)\) 后,上面的 \(q\) 其实就是虚儿子的 \(sum\) 平方再求和,那用类似的方法进行维护。然后再对这个东西再求一次路径和即可。最终用总的去减就是最终答案了。

代码

#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
template<typename T,typename _T>inline bool chk_min(T &x,const _T y){return y<x?x=y,1:0;}
template<typename T,typename _T>inline bool chk_max(T &x,const _T y){return x<y?x=y,1:0;}
typedef long long ll;
const int N=1e5+5;
const int P=1e9+7;
int ch[N][2],fa[N];bool rev[N];
int stk[N],tp;
int pw[N],sum[N],isum[N],Sum[N],ans[N];
int n,m; void create(int x,int val)
{
ch[x][0]=ch[x][1]=fa[x]=rev[x]=0;
pw[x]=sum[x]=val;
isum[x]=Sum[x]=ans[x]=0;
}
bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void reved(int x)
{
std::swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void push_up(int x)
{
sum[x]=((ll)sum[ch[x][0]]+sum[ch[x][1]]+pw[x]+isum[x])%P;
ans[x]=((ll)ans[ch[x][0]]+ans[ch[x][1]]+Sum[x])%P;
}
void push_down(int x)
{
if(rev[x])
{
if(ch[x][0])reved(ch[x][0]);
if(ch[x][1])reved(ch[x][1]);
rev[x]=0;
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y],k=(x==ch[y][1]);
if(!isroot(y))ch[z][y==ch[z][1]]=x; fa[x]=z;
ch[y][k]=ch[x][!k]; if(ch[x][!k])fa[ch[x][!k]]=y;
ch[x][!k]=y,fa[y]=x;
push_up(y),push_up(x);
}
void splay(int x)
{
stk[tp=1]=x;
for(int y=x;!isroot(y);y=fa[y])stk[++tp]=fa[y];
while(stk[tp])push_down(stk[tp]),tp--;
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(!isroot(y))(x==ch[y][1])==(y==ch[z][1])?rotate(y):rotate(x);
rotate(x);
}
}
void access(int x)
{
for(int y=0;x;y=x,x=fa[x])
{
splay(x);
(isum[x]+=(-(ll)sum[y]+sum[ch[x][1]])%P)%=P;
(Sum[x]+=(-(ll)sum[y]*sum[y]%P+(ll)sum[ch[x][1]]*sum[ch[x][1]])%P)%=P;
ch[x][1]=y;
push_up(x);
}
}
void make_root(int x)
{
access(x),splay(x),reved(x);
}
int get_root(int x)
{
access(x),splay(x);
while(ch[x][0])push_down(x),x=ch[x][0];
splay(x);
return x;
}
void link(int x,int y)
{
make_root(x),make_root(y);
fa[x]=y;
(isum[y]+=sum[x])%=P;
(Sum[y]+=(ll)sum[x]*sum[x]%P)%=P;
push_up(y);
}
void lift(int x,int y)
{
make_root(x),access(y),splay(x);
}
void update(int x,int val)
{
lift(x,x);
pw[x]=val;
push_up(x);
}
int query(int x,int y)
{
lift(x,y);
return (((ll)sum[x]*sum[x]%P-ans[x])%P+P)%P;
} int main()
{
while(~scanf("%d%d",&n,&m))
{
FOR(i,1,n)
{
int x;
scanf("%d",&x);
create(i,x);
}
FOR(i,1,n-1)
{
int u,v;
scanf("%d%d",&u,&v);
link(u,v);
}
while(m--)
{
int op,u,v;
scanf("%d%d%d",&op,&u,&v);
if(op==1)update(u,v);
else if(op==2)printf("%d\n",query(u,v));
}
}
return 0;
}

HDU 5405 Sometimes Naive(动态树)的更多相关文章

  1. 2015多校第9场 HDU 5405 Sometimes Naive 树链剖分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5405 题意: 给你一棵n个节点的树,有点权.        要求支持两种操作: 操作1:更改某个节点的 ...

  2. HDU 5405 Sometimes Naive 树链剖分+bit*****

    Sometimes Naive Problem Description   Rhason Cheung had a naive problem, and asked Teacher Mai for h ...

  3. HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)

    Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...

  4. HDU 2475 BOX 动态树 Link-Cut Tree

    Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem De ...

  5. hdu 5398 动态树LCT

    GCD Tree Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  6. hdu 5002 (动态树lct)

    Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  7. hdu 5314 动态树

    Happy King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  8. HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...

  9. HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树

    lca的做法还是非常明显的.简单粗暴, 只是不是正解.假设树是长链就会跪,直接变成O(n).. 最后跑的也挺快,出题人还是挺阳光的.. 动态树的解法也是听别人说能ac的.预计就是放在splay上剖分一 ...

随机推荐

  1. 移动端如何用swiper实现导航栏效果

    在移动端如何用swiper实现导航栏效果 我们在写移动端的时候会有滑动和点击导航后滑动到目标页面功能:而这个功能如果自己写的话会很麻烦,所以我在这推荐一下swiper这个插件. 其实swiper中的官 ...

  2. 我也来----xia bi bi 一下----微信小程序

    工作刚到一阶段 就看了看微信小程序  自己做了个小dome 主要是为了让我女朋友能够学习做菜! 然而悲催的发现我根本没有App ID   不说快了  直接上图 个人感觉开发起来还是很简单的. 对着AP ...

  3. Changing Ethernet Media Speed for AIX

    ITS UNIX Systems Changing Ethernet Media Speed for AIX First you need to find out the device name of ...

  4. nvm 淘宝镜像

    找到里面的settings.txt node_mirror: https://npm.taobao.org/mirrors/node/npm_mirror: https://npm.taobao.or ...

  5. POJ 1321 - 棋盘问题 - [经典DFS]

    题目链接:http://poj.org/problem?id=1321 Time Limit: 1000MS Memory Limit: 10000K Description 在一个给定形状的棋盘(形 ...

  6. Eclipse 00: 常用快捷键

    Eclipse常用快捷键 1几个最重要的快捷键 代码助手:Ctrl+Space(简体中文操作系统是Alt+/)快速修正:Ctrl+1单词补全:Alt+/打开外部Java文档:Shift+F2 显示搜索 ...

  7. 范进中Nature——儒林外史新义

    范进中Nature——儒林外史新义 范进发了文章回办公室,实验室一块儿搬砖的挂名作者俱各欢喜.正待烧锅煮方便面,只见他老板胡副教授,手里拿着一包外卖和一瓶红星二锅头,走了进来.范进向他作揖,坐下.胡副 ...

  8. XSS笔记

    XSS测试代码: <img src="javascript:alert(/xss/)"> <script src=http://evil.com/xss.js&g ...

  9. 关于systemctl

    systemctl是CentOS7的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体. 启动一个服务:systemctl start firewalld.servic ...

  10. cds view 创建和调用

    cds view 是一个core data service, 能够将数据库表虚拟化为一个虚拟表(double).因为各个使用sap的公司,使用的数据库数据是不同的,所以提供一个数据库的虚拟.  通过向 ...