cf1172E Nauuo and ODT(LCT)
首先可以转化问题,变为对每种颜色分别考虑不含该颜色的简单路径条数。然后把不是当前颜色的点视为白色,是当前颜色的点视为黑色,显然路径数量是每个白色连通块大小的平方和,然后题目变为:黑白两色的树,单点翻转颜色,维护白色连通块大小平方和,然后根据Auuan大佬的题解,我用了LCT。就是对每个点维护子树、儿子大小平方和,在 link/cut 的时候更新答案。初始化所有点是白色,离线处理每个颜色即可。
这题放在2h比赛上,除了lxl其他人都写不出来(况且lxl还是本题出题人呢)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+;
int n,m,c[N],f[N],fa[N],ch[N][],sum[N],sz[N];
ll ans,d[N],sz2[N];
bool vis[N];
vector<int>vec[N][],G[N];
bool nroot(int x){return x==ch[fa[x]][]||x==ch[fa[x]][];}
void pushup(int x){sum[x]=sum[ch[x][]]+sum[ch[x][]]+sz[x]+;}
void rotate(int x)
{
int y=fa[x],z=fa[y],w=x==ch[y][];
if(nroot(y))ch[z][y==ch[z][]]=x;
fa[x]=z,ch[y][w]=ch[x][w^],fa[ch[x][w^]]=y,ch[x][w^]=y,fa[y]=x;
pushup(y),pushup(x);
}
void splay(int x)
{
while(nroot(x))
{
int y=fa[x],z=fa[y];
if(nroot(y))
{
if((x==ch[y][])^(y==ch[z][]))rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int y=;
while(x)
{
splay(x);
sz[x]+=sum[ch[x][]]-sum[y];
sz2[x]+=1ll*sum[ch[x][]]*sum[ch[x][]]-1ll*sum[y]*sum[y];
ch[x][]=y;
pushup(x);
x=fa[y=x];
}
}
int findrt(int x)
{
access(x),splay(x);
while(ch[x][])x=ch[x][];
splay(x);
return x;
}
void link(int x)
{
int y=f[x],z;
splay(x);
ans-=sz2[x]+1ll*sum[ch[x][]]*sum[ch[x][]];
z=findrt(y);
access(x),splay(z);
ans-=1ll*sum[ch[z][]]*sum[ch[z][]];
fa[x]=y;
splay(y);
sz[y]+=sum[x],sz2[y]+=1ll*sum[x]*sum[x];
pushup(y),access(x),splay(z);
ans+=1ll*sum[ch[z][]]*sum[ch[z][]];
}
void cut(int x)
{
int y=f[x],z;
access(x);
ans+=sz2[x];
z=findrt(y);
access(x),splay(z);
ans-=1ll*sum[ch[z][]]*sum[ch[z][]];
splay(x);
ch[x][]=fa[ch[x][]]=;
pushup(x),splay(z);
ans+=1ll*sum[ch[z][]]*sum[ch[z][]];
}
void dfs(int u)
{for(int i=;i<G[u].size();i++)if(G[u][i]!=f[u])f[G[u][i]]=u,dfs(G[u][i]);}
int main()
{
scanf("%d%d",&n,&m);
ll lst;
for(int i=;i<=n;i++)
scanf("%d",&c[i]),vec[c[i]][].push_back(i),vec[c[i]][].push_back();
for(int i=;i<=n+;i++)sum[i]=;
for(int i=,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
for(int i=,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
vec[c[u]][].push_back(u),vec[c[u]][].push_back(i);
c[u]=v;
vec[v][].push_back(u),vec[v][].push_back(i);
}
f[]=n+;
dfs();
for(int i=;i<=n;i++)link(i);
for(int i=;i<=n;i++)
{
if(!vec[i][].size()){d[]+=1ll*n*n;continue;}
if(vec[i][][])d[]+=1ll*n*n,lst=1ll*n*n;else lst=;
for(int j=;j<vec[i][].size();j++)
{
int u=vec[i][][j];
if(vis[u]^=)cut(u);else link(u);
if(j==vec[i][].size()-||vec[i][][j+]!=vec[i][][j])
d[vec[i][][j]]+=ans-lst,lst=ans;
}
for(int j=vec[i][].size()-;~j;j--)
{
int u=vec[i][][j];
if(vis[u]^=)cut(u);else link(u);
}
}
ans=1ll*n*n*n;
for(int i=;i<=m;i++)ans-=d[i],printf("%lld\n",ans);
}
cf1172E Nauuo and ODT(LCT)的更多相关文章
- 【CF1172E】Nauuo and ODT(Link-Cut Tree)
[CF1172E]Nauuo and ODT(Link-Cut Tree) 题面 CF 给你一棵树,每个节点有一个颜色. 定义一条路径的权值为路径上不同颜色的数量.求所有有向路径的权值和. 有\(m\ ...
- CF1172E Nauuo and ODT
CF1172E Nauuo and ODT 神仙题orz 要算所有路径的不同颜色之和,多次修改,每次修改后询问. 对每种颜色\(c\)计算多少条路径包含了这个颜色,不好算所以算多少条路径不包含这个颜色 ...
- 「ZJOI2018」历史(LCT)
「ZJOI2018」历史(LCT) \(ZJOI\) 也就数据结构可做了-- 题意:给定每个点 \(access\) 次数,使轻重链切换次数最大,带修改. \(30pts:\) 挺好想的.发现切换次数 ...
- P4172 [WC2006]水管局长(LCT)
P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...
- 从ZOJ2114(Transportation Network)到Link-cut-tree(LCT)
[热烈庆祝ZOJ回归] [首先声明:LCT≠动态树,前者是一种数据结构,而后者是一类问题,即:LCT—解决—>动态树] Link-cut-tree(下文统称LCT)是一种强大的数据结构,不仅可以 ...
- 【洛谷4172】 [WC2006]水管局长(LCT)
传送门 洛谷 BZOJ Solution 如果不需要动态的话,那就是一个裸的最小生成树上的最大边权对吧. 现在动态了的话,把这个过程反着来,就是加边对吧. 现在问题变成了怎么动态维护加边的最小生成树, ...
- LCT总结——应用篇(附题单)(LCT)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--概念篇戳这里 题单 灰常感谢XZY巨佬提供的强力资磁!(可参考XZY巨佬的博客总结) 题单对于系 ...
- SP16580 QTREE7 - Query on a tree VII(LCT)
题意翻译 一棵树,每个点初始有个点权和颜色(输入会给你) 0 u:询问所有u,v路径上的最大点权,要满足u,v路径上所有点颜色相同 1 u:反转u的颜色 2 u w:把u的点权改成w 题解 Qtree ...
- SP16549 QTREE6 - Query on a tree VI(LCT)
题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...
随机推荐
- NumPy 数组创建
章节 Numpy 介绍 Numpy 安装 NumPy ndarray NumPy 数据类型 NumPy 数组创建 NumPy 基于已有数据创建数组 NumPy 基于数值区间创建数组 NumPy 数组切 ...
- jupiter的@TempDir 等不生效
jupiter与junit是 完全独立的测试组件,要严防在测试中将二者混用.最好在依赖引入jupiter 时 就将junit的依赖干掉,以防在写测试用例时将二者混用.不会报错,但是会导致 jupite ...
- webpack散记---代码分割 和 懒加载
webpack methods ES 2015 Loader spec (1)webpack methods方法 require.ensure //可以动态加载依赖 []:dependencies / ...
- canvas背景粒子动态变化动画
var canvas = document.getElementById("cas"); var ctx = canvas.getContext("2d"); ...
- 第六篇 ORM 操作大全
阅读目录(Content) 一 对象关系映射ORM概念 二 Django连接MySQL 三modles.py创建表 常用字段 字段合集 字段参数 DateField和DateTimeField 四.关 ...
- 洛谷 P2370 yyy2015c01的U盘
题目传送门 解题思路: 先将每个文件按照占空间从小到大排序,然后跑背包,当到了某一个文件时,价值够了,那么当前文件的体积就是答案. 其实本题是可以二分答案的,但是写挂了... AC代码: #inclu ...
- PHP循环语句练习题
<?php //输出0-100所有数字 for ($i=0; $i <101 ; $i++) { echo($i . '<br />'); }; //输出水仙花数 for ($ ...
- springboot入门学习1
springboot学习1 SpringBoot对Spring的缺点进行的改善和优化,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑 业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中 ...
- stm32h7 hal 库的学习
stm32h7xx_hal_conf.h 中需要注意的几个地方: HSE_VALUE 这个外接晶振的频率 TICK_INT_PRIORITY 这个 tick 的中断优先级,因为 HAL_DELAY 这 ...
- DevOps专题|Lua引擎打造超轻量级客户端
Lua 作为一门轻量级脚本语言,源码使用标准C语言发布,语法简洁,非常适合嵌入式.客户端.游戏等场景. Lua引擎语言特点 轻量级 源码简单,以lua最新版5.3.5为例,加上lua自身提供的lib库 ...