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上所有节点(包括)都拥 ...
随机推荐
- Bean XML 配置(1)- 通过XML配置加载Bean
系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of Contro ...
- CF1141E Superhero Battle
A superhero fights with a monster. The battle consists of rounds, each of which lasts exactly n minu ...
- wireshark封包详细信息详解(10.15 第二十一天)
wireshark:网络流量抓取分析神器,需要学习一些常用的数据包过滤规则 IP过滤 ip.addr==192.168.1.1 只要包中的IP有192.168.1.1的,就会提取过来 IP源地址:ip ...
- P 1023 组个最小数
转跳点:
- 每天一点点之vue框架开发 - History 模式下线上路由报404错误
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载. 如果不想要很丑的 hash,我们可以用路由的 his ...
- redis qps监控
最近有个客户反应redis的qps不准确,通过查看代码,发现我们的监控是调用的redis info里面的instantaneous_ops_per_sec 客户反应说自己压测了ns,但是从监控上看不到 ...
- (2) JVM内存管理:垃圾回收
回顾上期 1)JVM中引用存在哪里? 答:虚拟机栈,该内存空间线程独有 2)该引用的对象存在哪里? 答:堆,所有通过new方法分配的对象都存在堆中 3)String s1="abc" ...
- Day 11:静态导入、增强for循环、可变参数的自动装箱与拆箱
jdk1.5新特性-------静态导入 静态导入的作用: 简化书写. 静态导入可以作用一个类的所有静态成员. 静态导入的格式:import static 包名.类名.静态的成员: 静态导入要注意的 ...
- Map—数据结构
map是数据结构的一种,map总是以key-value的形式保存数据的, 根据key来查找value的值,但是key的值是唯一的,在同一个map中不能重复. 常用的实现类java.util.hashM ...
- Codeforces 1299B/1300D - Aerodynamic
题目大意: 给定一个图形S,让这个图形任意平移,但是要保证原点(0,0)一直在它的内部或者边上 最后把它能移动到的所有位置进行拼合可以得到一个图形T 问图形S与图形T是否相似 点会按照逆时针顺序给出 ...