题目: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的更多相关文章

  1. Codeforces 1172E Nauuo and ODT [LCT]

    Codeforces ZROI那题是这题删掉修改的弱化版--ZROI还我培训费/px 思路 按照套路,我们考虑每种颜色的贡献,然后发现不包含某种颜色的路径条数更容易数,就是删掉该颜色的点后每个连通块大 ...

  2. 【杂题】[CodeForces 1172E] Nauuo and ODT【LCT】【口胡】

    Description 给出一棵n个节点的树,每个点有一个1~n的颜色 有m次操作,每次操作修改一个点的颜色 需要在每次操作后回答树上\(n^2\)条路径每条路径经过的颜色种类数和. \(n,m< ...

  3. CF1172E Nauuo and ODT LCT

    自己独立想出来的,超级开心 一开始想的是对于每一个点分别算这个点对答案的贡献. 但是呢,我们发现由于每一条路径的贡献是该路径颜色种类数,而每个颜色可能出现多次,所以这样就特别不好算贡献. 那么,还是上 ...

  4. 【CodeForces】1172E. Nauuo and ODT

    题解 看了一遍题解(以及代码)但是没写代码-- 后来做梦的时候忽然梦到了这道题--意识到我需要补一下-- 这道题就是,对于每种颜色,把没有染成这种颜色的点标成黑点,然后计算每个联通块的平方 然后每个点 ...

  5. 【CF1172E】Nauuo and ODT(Link-Cut Tree)

    [CF1172E]Nauuo and ODT(Link-Cut Tree) 题面 CF 给你一棵树,每个节点有一个颜色. 定义一条路径的权值为路径上不同颜色的数量.求所有有向路径的权值和. 有\(m\ ...

  6. CF1172E Nauuo and ODT

    CF1172E Nauuo and ODT 神仙题orz 要算所有路径的不同颜色之和,多次修改,每次修改后询问. 对每种颜色\(c\)计算多少条路径包含了这个颜色,不好算所以算多少条路径不包含这个颜色 ...

  7. cf1172E Nauuo and ODT(LCT)

    首先可以转化问题,变为对每种颜色分别考虑不含该颜色的简单路径条数.然后把不是当前颜色的点视为白色,是当前颜色的点视为黑色,显然路径数量是每个白色连通块大小的平方和,然后题目变为:黑白两色的树,单点翻转 ...

  8. [CF1172E]Nauuo and ODT:Link-Cut Tree

    分析 lxl大毒瘤. 感谢Ouuan等CNOIER提供了这么好的比赛. 这里只是把官方题解复述一遍,可以直接去看官方题解:点我. 考虑将问题转化为对于每个颜色,求出没有经过这个颜色的节点的路径有多少条 ...

  9. 题解 CF1172E Nauuo and ODT

    题目传送门 题目大意 给出一个 \(n\) 个点的树,每个点有颜色,定义 \(\text{dis}(u,v)\) 为两个点之间不同颜色个数,有 \(m\) 次修改,每次将某个点的颜色进行更改,在每次操 ...

随机推荐

  1. php面向对象重的抽象类,接口类与静态

    static 静态 <?php class ren { public $name; public static $sex; static function shao() { echo " ...

  2. Myeclipse优化配置

    #utf8 (do not remove)#utf8 (do not remove)-startup../Common/plugins/org.eclipse.equinox.launcher_1.2 ...

  3. H3C CAS 介绍 & 基本概念

    目录 目录 基本概念 H3C CAS 中的虚拟机 虚拟机中的虚拟设备 虚拟 CPU 的 3 种工作模式 虚拟网卡的 3 种类型 虚拟磁盘的三种类型 虚拟机辅助工具 CAS Tools 虚拟机外的虚拟设 ...

  4. Integer自动装箱和拆箱

    Integer a=3;   =>    Integer a=Integer.valueOf(3); /** *@description: 自动装箱和拆箱 *@auther: yangsj *@ ...

  5. 使用eclipse制作war包方法 web项目打包到tomcat

    打开eclipse在左侧右击项目名选择“Export”   在导出画面点击 “Web”->“WAR file”点击“Next”   点击“Browse…”选择文件的导出位置,Target run ...

  6. Entity Framework Code First (五)Fluent API - 配置关系 转载 https://www.cnblogs.com/panchunting/p/entity-framework-code-first-fluent-api-configuring-relationships.html

    上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的. 文中所使用代码如下 public class Student { public int ...

  7. JSP中四种属性保存范围(1)

    一.四种属性范围 在JSP中提供了四种属性保存范围 page:在一个页面内保存属性,跳转之后无效request:在一次服务请求范围内,服务器跳转后依然有效session:-在一次会话范围内,无论何种跳 ...

  8. 回调-> 观察者模式->反应堆模式

    关于回调: 回调是观察者模式以及反应堆模式的基础 一句话,回调就是一种双向调用模式,什么意思呢,就是说,被调用方在被调用时也会调用对方,这就叫回调.“If you call me, i will ca ...

  9. IDF-CTF-牛刀小试 writeup

    题目链接:http://ctf.idf.cn/index.php?g=game&m=list&a=index&id=16 被改错的密码 从前有一个熊孩子入侵了一个网站的数据库, ...

  10. solr的moreLikeThis实现“相似数据”功能

    在我们使用网页搜索时,会注意到每一个结果都包含一个 “相似页面” 链接,单击该链接,就会发布另一个搜索请求,查找出与起初结果类似的文档.Solr 使用 MoreLikeThisComponent(ML ...