题目: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. IQueryable不能使用异步方法的解决方案

    ---恢复内容开始--- 看见别人用Linq to Sql的Async好久了,我还没开始用,感觉太土了,跟不上潮流了,打开vs,就准备写个查询,然后发现我用一个IQueryable的对象,怎么都点不出 ...

  2. tomcat中的server.xml文件配置了URIEncoding="UTF-8"需要注意的问题

    1.      get请求传递中文时本地连正式库访问都正常,正式环境下单独访问报错 代码: 请求:project/projectInfo/export/?cks=’项目类型 public String ...

  3. Support Vector Machine(1):线性可分集的决策边界

    与Logistuc Regression相比,SVM是一种优化的分类算法,其动机是寻找一个最佳的决策边界,使得从决策边界与各组数据之间存在margin,并且需要使各侧的margin最大化.比较容易理解 ...

  4. nodejs基础-HTTP

    案例通过nodejs编写http服务程序 步骤:1,加载http模块2.创建http服务3.为http服务对象添加request事件处理程序4·开启http服务监听,准备接收客户端请求注意:1,浏览器 ...

  5. hashCode -哈希值,Object中的方法,常根据实际情况重写

    package cn.learn.collection; import cn.learn.basic.Phone; /* 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值),是一个逻辑地址 ...

  6. Scala函数高级操作

    字符串高级操作:***** 非常重要 将函数赋值给变量/值def sayHello(name:String): Unit = { println(s"Hello:$name")} ...

  7. Python入门习题9.数码管时间

    #七段数码管.py import turtle,datetime def drawGap(): #绘制数码管间隔 turtle.penup() turtle.fd(5) def drawLine(dr ...

  8. python学习第八天二进制和字符编码有关联

    计算机所能识别只有0,1这两种状态,但是我们人类用字母,汉字,还有其他语言,那么怎么和计算机进行沟通呢,python编程语言最早unicode,现在统一用utf8,UTF8通用的编码语言,所有语言都包 ...

  9. Crash的数字表格(莫比乌斯反演)

    Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b ...

  10. PHP中redis加锁和解锁的简单实现

    背景说明 在程序开发过程中,通常会遇到需要独占式的访问一些资源的情形,比如商品秒杀时扣减库存.这时就需要对资源加锁.实现锁的方式有很多,比如数据库锁.文件锁等等.本文简单介绍PHP中使用redis来实 ...