【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 给出一些数字,对于每个数字找到一个欧拉函数值大于等于这个数的数,求找到的所有数的最小和. 题解 首先 ...
随机推荐
- Nginx + FastCGI + Django在windows上部署及nginx常用命令
一般应用都是部署在linux系统上,不会在windows上部署,emmm..所以有兴趣的就瞧瞧吧哈哈 nginx工作原理: nginx用于处理静态文件,动态部分经由fastcgi .scgi或uWSG ...
- golang+webgl实践激光雷达(一)激光扫描仪基础知识
一.前言 最近做一个测量料堆形状的项目,通过前期调研,最后决定用激光测距原理进行测量.通过旋转云台+激光扫描仪实现空间三维坐标的测量.其中激光扫描仪扫射的是一个二维的扫描面,再通过云台旋转,则形成一个 ...
- Linux中ps -elf和ps aux的区别
一.前言 Linux下输入命令man ps查看: 加横线是 standard syntax -- 比如ps -elf 不加横线是 BSD syntax -- 比如ps aux To see ...
- (day68)Vue-CLI项目、页面跳转和传参、生命周期钩子
目录 一.Vue-CLI (一)环境搭建 (二)项目的创建 (三)项目目录结构 (四)Vue组件(.vue文件) (五)全局脚本文件main.js(项目入口) (六)Vue请求生命周期 二.页面跳转和 ...
- 范罗士空气净化器PT65评测
买了一台空气净化器,之前网上查了查,哟,是个知名品牌,做碎纸机的. 你问我为啥找个卖碎纸机的买空气净化器?因为年轻,咱们往下看 包装还可以 一打开就有疑问了,这塑料味道不对呀,三手料也不该这个味儿啊. ...
- 基于V7的新版RL-USB和RL-FlashFS的NAND完整解决方案,实现更简单,用户仅需初始化FMC
说明: 1.新版方案更加好用,不管用户使用的那家NAND,用户要做的仅仅是初始化FMC,其它读写API,擦写均衡,坏块管理,ECC校验和掉电保护都不用操心了. 2.新版RL-USB相比老版本功能强劲了 ...
- 为Bootstrap Modal(模态框)全局添加拖拽操作
在js中绑定方法 $(document).on("show.bs.modal", ".modal", function(){ $(this).draggable ...
- NoiseSystem数据库设计心得-洋芋好想飞
团队:洋芋好想飞 成员:乔祥硕 石高飞 杨慧慧 梁家豪 潘景渝 整理:乔祥硕 PM乔祥硕: 10月25日14:30到17:30,10月27日14:30到17:30,11月1日14:30到17:30,这 ...
- canvas绘制星星和月亮
用变量的方式绘制一个五角星,首先求五角星十个顶点的坐标. 可以把每个五角星看成外顶点用一个大圆绘制,内顶点用小圆绘制.在坐标系(0deg)下,根据每个顶点的角度和圆的半径求得x,y. 而每个大顶点相差 ...
- vue-cli 引用elementUI打包后文件过大
解决方案:使用externals引用第三方资源,防止element资源被打包到自己项目中,(总共修改3个页面index.html.webpack.base.conf.js.main.js) 1.修改i ...