【CF1172E】Nauuo and ODT(Link-Cut Tree)
【CF1172E】Nauuo and ODT(Link-Cut Tree)
题面
CF
给你一棵树,每个节点有一个颜色。
定义一条路径的权值为路径上不同颜色的数量。求所有有向路径的权值和。
有\(m\)次单点颜色修改操作,每次修改之后输出答案。
题解
如果只有黑白两色,我们要求白色的贡献,那么我们可以把所有白色节点删去,那么答案就是每个黑色连通块的\(size\)平方和。考虑怎么动态维护这个东西。
要做的是,一开始我们的所有节点都是黑点,然后有若干次颜色取反操作,每次求黑色连通块的\(size^2\)的和。
然后拿\(LCT\)维护这个东西,在修改父子关系的时候修改答案。
因为维护的是子树和,所以要维护虚子树信息。
为了防止根节点被染黑不会发生父子关系变化,所以给根节点再额外加一个父亲就好了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 400400
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
namespace LCT
{
#define ls (t[x].ch[0])
#define rs (t[x].ch[1])
ll Num;
struct Node{int ff,ch[2],sz,vsz;ll ssz;ll Val(){return 1ll*sz*sz;}}t[MAX];
bool isroot(int x){return t[t[x].ff].ch[0]!=x&&t[t[x].ff].ch[1]!=x;}
void pushup(int x){t[x].sz=t[ls].sz+t[rs].sz+t[x].vsz+1;}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);pushup(x);
}
void Splay(int x)
{
while(!isroot(x))
{
int y=t[x].ff,z=t[y].ff;
if(!isroot(y))
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x)
{
for(int y=0;x;y=x,x=t[x].ff)
{
Splay(x);
t[x].vsz-=t[y].sz;
t[x].vsz+=t[rs].sz;
t[x].ssz-=t[y].Val();
t[x].ssz+=t[rs].Val();
rs=y;pushup(x);
}
}
int findroot(int x){access(x);Splay(x);while(ls)x=ls;Splay(x);return x;}
void link(int x,int y)
{
Splay(x);
Num-=t[x].ssz+t[rs].Val();
int z=findroot(y);
access(x);Splay(z);
Num-=t[t[z].ch[1]].Val();
t[x].ff=y;Splay(y);
t[y].vsz+=t[x].sz;
t[y].ssz+=t[x].Val();
pushup(y);access(x);
Splay(z);
Num+=t[t[z].ch[1]].Val();
}
void cut(int x,int y)
{
access(x);Num+=t[x].ssz;
int z=findroot(y);
access(x);Splay(z);
Num-=t[t[z].ch[1]].Val();
Splay(x);
t[x].ch[0]=t[t[x].ch[0]].ff=0;
pushup(x);Splay(z);
Num+=t[t[z].ch[1]].Val();
}
}
using namespace LCT;
vector<int> E[MAX];
vector<pair<int,int> >V[MAX];
int n,m,c[MAX],fa[MAX],col[MAX];ll Ans[MAX];
void dfs(int u,int ff){fa[u]=ff;for(int v:E[u])if(v!=ff)dfs(v,u);}
int main()
{
freopen("a.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;++i)c[i]=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
E[u].push_back(v);
E[v].push_back(u);
}
for(int i=1;i<=n;++i)V[c[i]].push_back(make_pair(0,i));
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
V[c[u]].push_back(make_pair(i,u));
c[u]=v;
V[c[u]].push_back(make_pair(i,u));
}
dfs(1,n+1);
for(int i=1;i<=n+1;++i)pushup(i);
for(int i=1;i<=n;++i)link(i,fa[i]);
for(int i=1;i<=n;++i)
{
ll lst=0;
for(auto a:V[i])
{
int u=a.second,t=a.first;
col[u]?link(u,fa[u]):cut(u,fa[u]);
col[u]^=1;
Ans[t]+=1ll*n*n-Num-lst;
lst=1ll*n*n-Num;
}
for(auto a:V[i])
{
int u=a.second;
if(col[u])link(u,fa[u]),col[u]^=1;
}
}
for(int i=1;i<=m;++i)Ans[i]+=Ans[i-1];
for(int i=0;i<=m;++i)printf("%lld\n",Ans[i]);
return 0;
}
【CF1172E】Nauuo and ODT(Link-Cut Tree)的更多相关文章
- LCT(Link Cut Tree)总结
概念.性质简述 首先介绍一下链剖分的概念链剖分,是指一类对树的边进行轻重划分的操作,这样做的目的是为了减少某些链上的修改.查询等操作的复杂度.目前总共有三类:重链剖分,实链剖分和并不常见的长链剖分. ...
- 【cf600】E. Lomsat gelral(dsu on tree)
传送门 题意: 求子树众数. 思路: \(dsu\ on\ tree\)模板题,用一个桶记录即可. 感觉\(dsu\ on\ tree\)这个算法的涉及真是巧妙呀,保留重链的信息,不断暴力轻边,并且不 ...
- SSAS系列——【08】多维数据(程序展现Cube)
原文:SSAS系列--[08]多维数据(程序展现Cube) 1.引用DLL? 按照之前安装的MS SQLServer的步骤安装完成后,发现在新建的项目中“Add Reference”时居然找不到Mic ...
- 洛谷 P3377 【模板】左偏树(可并堆)
洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ...
- 【BZOJ2342】双倍回文(回文树)
[BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...
- 【BZOJ2337】Xor和路径(高斯消元)
[BZOJ2337]Xor和路径(高斯消元) 题面 BZOJ 题解 我应该多学点套路: 对于xor之类的位运算,要想到每一位拆开算贡献 所以,对于每一位拆开来看 好了,既然是按位来算 我们就只需要计算 ...
- 【BZOJ4372】烁烁的游戏(动态点分治)
[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...
- 【BZOJ1013】球形空间产生器(高斯消元)
[BZOJ1013]球形空间产生器(高斯消元) 题面 Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标, ...
- 【LightOJ1370】Bi-shoe and Phi-shoe(欧拉函数)
[LightOJ1370]Bi-shoe and Phi-shoe(欧拉函数) 题面 Vjudge 给出一些数字,对于每个数字找到一个欧拉函数值大于等于这个数的数,求找到的所有数的最小和. 题解 首先 ...
随机推荐
- Pairs Forming LCM (LightOJ - 1236)【简单数论】【质因数分解】【算术基本定理】(未完成)
Pairs Forming LCM (LightOJ - 1236)[简单数论][质因数分解][算术基本定理](未完成) 标签: 入门讲座题解 数论 题目描述 Find the result of t ...
- java之模板方法设计模式
抽象类体现的就是一种模板模式的设计.抽象类作为多个子类的通用模板.子类在抽象类的基础上进行扩张和改造,但子类总体上会保留抽象类的行为方式. 解决的问题: 当功能内部一部分实现是确定的,一部分实现是不确 ...
- Java入门总结
1. 一个Java源码只能定义一个public类型的class,并且class名称和文件名要完全一致: 使用javac可以将.java源码编译成.class字节码: 使用java可以运行一个已编译的J ...
- 上海街头灵魂摄影师:勤劳de小懒熊
上海中年大叔,街头摄影师,眼光比较独特,题材不限于: 酒吧晚上醉酒躺尸的.喝多亲嘴的.拉拉les的.流泪告别的.地铁露肉的.短裤露沟的. 尺度不大,但比较真实,艺术来源于生活,比那些摆拍的有意思. 大 ...
- ubuntu18.04 安装 WPS 2019
ubuntu自带的文字处理软件对来自windows下office或在WPS创建的ppt有点不兼容,看到WPS有linux版本的,便果断安装试一试. 一.卸载原生liboffice sudo apt-g ...
- Python实现变声器功能,萝莉音御姐音都有的哦
登录百度AL开发平台 在控制台选择语音合成 创建应用 填写应用信息 在应用列表获取(Appid.API Key.Secret Key) 6. 安装pythonsdk 安装使用Python SDK有如下 ...
- GO基础之函数的高级用法
一.可变参数 支持可变长参数列表的函数可以支持任意个传入参数,比如fmt.Println函数就是一个支持可变长参数列表的函数. package main import "fmt" ...
- Bootstrap基本CSS样式
一.简介.使用 1.简介 Bootstrap 来源于 Twitter,是一款基于 Html.Css.JavaScript 的前端UI框架.可以方便.快速的开发web界面. 教程:https://www ...
- easyui-datagrid 使用笔记
1.清空所有行和所有列 $('#dgJGQuery').datagrid({ columns: [], url: '', data: [] }); 2.采用 datagrid-groupview 分组 ...
- GPS NMEA-0183协议常用报文数据格式
点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 整理的GPS有关的协议分析资料." 之前分析一些车载设备的流量时,有部分经验,在这里和大家分享. 产生这些流量的设备通常是实体终端 ...