CF 1172E Nauuo and ODT ——LCT
题目:http://codeforces.com/contest/1172/problem/E
LCT好题。
考虑对每个颜色求出 “不是该颜色的点组成的连通块的 siz2 之和” 。每个颜色用 LCT 维护不是该颜色的点。
LCT 维护的一个连通块,其最顶端的点是该颜色,其他部分满足 “不是该颜色” ;再维护子树的 siz2 ,就能做了。
注意代码里的 p[ ] 要开 2*n 那么大!!!
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
ll Sqr(int x){return (ll)x*x;}
const int N=4e5+,M=N<<;
int n,m,col[N],hd[N],xnt,to[M],nxt[M];
int f[N],fa[N],c[N][],siz[N],sizi[N];
int p[M],tot; bool vis[N];ll siz2i[N],tmp,dlt[N];//p[M]!!
bool isrt(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
void pshp(int x){siz[x]=siz[c[x][]]+siz[c[x][]]+sizi[x]+;}
void rotate(int x)
{
int y=fa[x],z=fa[y]; bool d=(x==c[y][]);
if(!isrt(y))c[z][y==c[z][]]=x;
fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
c[y][d]=c[x][!d]; c[x][!d]=y;
pshp(y); pshp(x);
}
void splay(int x)
{
for(int y,z;!isrt(x);rotate(x))
{
y=fa[x]; z=fa[y];
if(!isrt(y))
((y==c[z][])^(x==c[y][]))?rotate(x):rotate(y);
}
}
void access(int x)
{
for(int t=;x;t=x,x=fa[x])
{
splay(x); int y=c[x][];
sizi[x]+=siz[y]; siz2i[x]+=Sqr(siz[y]);
sizi[x]-=siz[t]; siz2i[x]-=Sqr(siz[t]);
c[x][]=t; pshp(x);
}
}
int fnd_rt(int x)
{
access(x); splay(x);
while(c[x][])x=c[x][];
splay(x); return x;
}
void link(int x)
{
splay(x);//x is top so always accessed
tmp-=Sqr(siz[c[x][]])+siz2i[x];
int y=f[x],rt=fnd_rt(y);//rt splayed
splay(rt);///y accessed
tmp-=Sqr(siz[c[rt][]]);////+siz2i[rt];
splay(y); fa[x]=y;
sizi[y]+=siz[x]; siz2i[y]+=Sqr(siz[x]); pshp(y);
access(x); splay(rt);//access(x)!!!
tmp+=Sqr(siz[c[rt][]]);
}
void cut(int x)
{
int rt=fnd_rt(x);//x accessed//rt splayed
tmp+=siz2i[x];//!!!
tmp-=Sqr(siz[c[rt][]]);
int y=f[x]; splay(y); c[y][]=; fa[x]=; pshp(y);
//x accessed and is bottom so is c[y][1]
splay(rt);
tmp+=Sqr(siz[c[rt][]]);
}
namespace Q{
int hd[N],xnt,to[M],id[M],nxt[M];
void add(int x,int y,int i)
{
to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;id[xnt]=i;
}
void solve(int cr)
{
tot=;
for(int i=hd[cr];i;i=nxt[i])
p[++tot]=i;
for(int i=tot,d;i;i--)
{
tmp=; d=p[i];
if(vis[to[d]]) link(to[d]);
else cut(to[d]);
dlt[id[d]]+=tmp;
vis[to[d]]^=;
}
}
void solve2(int cr)
{
for(int i=hd[cr];i;i=nxt[i])
{
tmp=;
if(vis[to[i]]) link(to[i]);
else cut(to[i]);
vis[to[i]]^=;
}
}
}
namespace I{
int hd[N],xnt,to[N],nxt[N];
void add(int x,int y)
{to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
void solve(int cr)
{
tot=;
for(int i=hd[cr];i;i=nxt[i])
p[++tot]=to[i];
tmp=;
for(int i=tot;i;i--)
{
if(vis[p[i]]) link(p[i]);
else cut(p[i]);
vis[p[i]]^=;
}
dlt[]+=tmp;
}
void solve2(int cr)
{
for(int i=hd[cr];i;i=nxt[i])
{
tmp=;
if(vis[to[i]]) link(to[i]);
else cut(to[i]);
vis[to[i]]^=;///
}
}
}
void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
void ini_dfs(int cr,int fa)
{
f[cr]=fa;
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=fa) ini_dfs(v,cr);
}
int main()
{
n=rdn();m=rdn();
for(int i=;i<=n+;i++)
{ col[i]=rdn(); I::add(col[i],i);}
for(int i=,u,v;i<n;i++)
u=rdn()+,v=rdn()+,add(u,v),add(v,u);
add(,); add(,); ini_dfs(,);
for(int i=,u,d;i<=m;i++)
{
u=rdn()+; d=rdn(); Q::add(col[u],u,i);
col[u]=d; Q::add(d,u,i);
}
for(int i=;i<=n+;i++)siz[i]=;//
for(int i=;i<=n+;i++) link(i);
dlt[]=(ll)n*n*n;
for(int i=;i<=n;i++)
{
I::solve(i); Q::solve(i);
Q::solve2(i); I::solve2(i);
}
ll ans=(ll)n*n*n;
for(int i=;i<=m;i++)
{
ans-=dlt[i]; printf("%lld\n",ans);
}
return ;
}
CF 1172E Nauuo and ODT ——LCT的更多相关文章
- Codeforces 1172E Nauuo and ODT [LCT]
Codeforces ZROI那题是这题删掉修改的弱化版--ZROI还我培训费/px 思路 按照套路,我们考虑每种颜色的贡献,然后发现不包含某种颜色的路径条数更容易数,就是删掉该颜色的点后每个连通块大 ...
- 【杂题】[CodeForces 1172E] Nauuo and ODT【LCT】【口胡】
Description 给出一棵n个节点的树,每个点有一个1~n的颜色 有m次操作,每次操作修改一个点的颜色 需要在每次操作后回答树上\(n^2\)条路径每条路径经过的颜色种类数和. \(n,m< ...
- CF1172E Nauuo and ODT LCT
自己独立想出来的,超级开心 一开始想的是对于每一个点分别算这个点对答案的贡献. 但是呢,我们发现由于每一条路径的贡献是该路径颜色种类数,而每个颜色可能出现多次,所以这样就特别不好算贡献. 那么,还是上 ...
- 【CodeForces】1172E. Nauuo and ODT
题解 看了一遍题解(以及代码)但是没写代码-- 后来做梦的时候忽然梦到了这道题--意识到我需要补一下-- 这道题就是,对于每种颜色,把没有染成这种颜色的点标成黑点,然后计算每个联通块的平方 然后每个点 ...
- 【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\)计算多少条路径包含了这个颜色,不好算所以算多少条路径不包含这个颜色 ...
- cf1172E Nauuo and ODT(LCT)
首先可以转化问题,变为对每种颜色分别考虑不含该颜色的简单路径条数.然后把不是当前颜色的点视为白色,是当前颜色的点视为黑色,显然路径数量是每个白色连通块大小的平方和,然后题目变为:黑白两色的树,单点翻转 ...
- [CF1172E]Nauuo and ODT:Link-Cut Tree
分析 lxl大毒瘤. 感谢Ouuan等CNOIER提供了这么好的比赛. 这里只是把官方题解复述一遍,可以直接去看官方题解:点我. 考虑将问题转化为对于每个颜色,求出没有经过这个颜色的节点的路径有多少条 ...
- 题解 CF1172E Nauuo and ODT
题目传送门 题目大意 给出一个 \(n\) 个点的树,每个点有颜色,定义 \(\text{dis}(u,v)\) 为两个点之间不同颜色个数,有 \(m\) 次修改,每次将某个点的颜色进行更改,在每次操 ...
随机推荐
- jmeter之ServerAgent监控资源
对linux服务器的服务进行压测时,服务器的运行情况可以通过添加插件来观察,而不用使用top命令实时的去看 1.资源准备 2.环境准备 3.资源监控 1.资源准备 可通过该网址下载jmeter所有插件 ...
- 把任意的EXE嵌入到自己程序中
把任意的EXE嵌入到自己程序中 taoyuan19822008-08-24上传 Delphi把任意的EXE嵌入到自己程序中的程序 资源积分:0分 下载次数:327 资源类型:其他 资源大小:175 ...
- 16/7/11_PHP-数据库操作
PHP支持哪些数据库 PHP通过安装相应的扩展来实现数据库操作,现代应用程序的设计离不开数据库的应用,当前主流的数据库有MsSQL,MySQL,Sybase,Db2,Oracle,PostgreSQL ...
- Effect Hook
1 数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用. 2 可以把 useEffect Hook 看做 componentDidMount,componentDidUpdat ...
- jmeter两种录制方式
jmeter两种录制方式 一.Badboy Badboy是一款不错web自动化测试工具,利用它来录制脚本,并且录制的脚本可以直接保存为JMeter文件来使用. Badboy version 2.1. ...
- Git009--分支管理&创建与合并分支
Git--分支管理&创建与合并分支 一.分支管理 本文来自于:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578 ...
- < python PIL - 批量图像处理 - RGB图像生成灰度图像 >
< python PIL - 批量图像处理 - RGB图像生成灰度图像 > 直接用python自带的PIL图像库,将一个文件夹下所有jpg/png的RGB图像转换成灰度/黑白图像 from ...
- java包装类,自动装箱,拆箱,以及基本数据类型与字符串的转换
package cn.learn; import java.util.ArrayList; /* 包装类 java.lang中,基本运算类型效率高 装箱:把基本类型数据包装为包装类 1.构造方法 In ...
- spring-第二篇ApplicationContext国际化及事件机制
1.ApplicationContext接口获取spring容器 ApplicationContext是BeanFactory接口的子接口,BeanFactory的常用实现类是Default ...
- vmware linux root密码破解
centOS: 1.开机过程按上下箭头键,让系统不要进入到引导程序中, 2.按 'e' 进入到编辑模式 3.找到linux16开始的首行,在末尾加入'rw init=/bin/sh' (会出现修改密码 ...