题解

看了一遍题解(以及代码)但是没写代码……

后来做梦的时候忽然梦到了这道题……意识到我需要补一下……

这道题就是,对于每种颜色,把没有染成这种颜色的点标成黑点,然后计算每个联通块的平方

然后每个点维护,虚儿子黑点的siz,虚儿子的siz的平方,还有splay上的siz和

为了保证最高点是白点,我们新建一个点建到根上面

然后把一个点染黑就相当于断掉所有儿子,然后减去所有虚儿子siz的平方,然后顺着fa找到最高的白点,删掉这个白点原先右边挂着的树,然后再减去这个白点原先右边挂着的部分,这个点再连上父亲,再找到最高的白点,重新统计白点右边挂着的部分

把一个点染白相当于找到最高的白点,然后右边挂着的树给删掉,然后加上x所在的虚儿子siz的平方,再最高的白点新的右子树大小

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <random>
#include <ctime>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 400005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N,M;
int c[MAXN],b[MAXN];
int64 ans,del[MAXN];
struct node {
int lc,rc,fa;
int64 siz2i,siz,sizi;
}tr[MAXN];
#define rc(u) tr[u].rc
#define lc(u) tr[u].lc
#define fa(u) tr[u].fa
#define siz(u) tr[u].siz
#define siz2i(u) tr[u].siz2i
#define sizi(u) tr[u].sizi
int fa[MAXN];
vector<int> E[MAXN];
vector<pii > col[MAXN];
void dfs(int u) {
for(auto v : E[u]) {
if(v != fa[u]) {
fa[v] = u;
dfs(v);
}
}
}
int64 o(int64 x) {
return x * x;
}
bool isRoot(int x) {
if(!fa(x)) return true;
else return lc(fa(x)) != x && rc(fa(x)) != x;
}
bool which(int x) {
return rc(fa(x)) == x;
}
void update(int u) {
siz(u) = sizi(u) + siz(rc(u)) + siz(lc(u)) + 1;
}
void rotate(int u) {
int v = fa(u),w = fa(v);
if(!isRoot(v)) {(v == lc(w) ? lc(w) : rc(w)) = u;}
fa(u) = w;fa(v) = u;
int b = u == lc(v) ? rc(u) : lc(u);
if(b) fa(b) = v;
if(u == lc(v)) {rc(u) = v;lc(v) = b;}
else {lc(u) = v;rc(v) = b;}
update(v);
}
void Splay(int u) {
while(!isRoot(u)) {
if(!isRoot(fa(u))) {
if(which(u) == which(fa(u))) rotate(fa(u));
else rotate(u);
}
rotate(u);
}
update(u);
}
void Access(int u) {
for(int x = 0 ; u ; x = u, u = fa(u)) {
Splay(u);
sizi(u) += siz(rc(u));
sizi(u) -= siz(x);
siz2i(u) += o(siz(rc(u)));
siz2i(u) -= o(siz(x));
rc(u) = x;
update(u);
}
}
int FindRoot(int x) {
Access(x);Splay(x);
int p = x;
while(lc(p)) p = lc(p);
return p;
}
void Link(int x) {
int y = fa[x],z = FindRoot(y);
Access(y);Splay(z);
ans -= o(siz(rc(z)));
Access(x);
ans -= siz2i(x);
tr[x].fa = y;
Splay(y);
siz2i(y) += o(siz(x));
sizi(y) += siz(x);
update(y);
Access(x);Splay(z);//这里要Access(x)因为可能y是一个白点
ans += o(siz(rc(z)));
}
void Cut(int x) {
int y = fa[x],z = FindRoot(y);
Access(x);Splay(z);
ans -= o(siz(rc(z)));
ans += siz2i(x);
Splay(y);
rc(y) = 0;fa(x) = 0;update(y);
Splay(z);
ans += o(siz(rc(z)));
}
void Init() {
read(N);read(M);
for(int i = 1 ; i <= N ; ++i) read(c[i]);
int a,b;
for(int i = 1 ; i < N ; ++i) {
read(a);read(b);
E[a].pb(b);E[b].pb(a);
}
dfs(1);fa[1] = N + 1;
for(int i = 1 ; i <= N ; ++i) {
col[c[i]].pb(mp(0,i));
}
for(int i = 1 ; i <= M ; ++i) {
read(a);read(b);
col[b].pb(mp(i,a));
col[c[a]].pb(mp(i,a));
c[a] = b;
} }
void Solve() {
for(int i = 1 ; i <= N ; ++i) {siz(i) = 1;Link(i);}
for(int i = 1 ; i <= N ; ++i) {
del[0] += 1LL * N * N;
int64 pre = 1LL * N * N;
for(int j = 0 ; j < col[i].size() ; ++j) {
int t = j;
del[col[i][j].fi] -= pre;
while(t + 1 < col[i].size() && col[i][t + 1].fi == col[i][j].fi) ++t;
for(int h = j ; h <= t ; ++h) {
if(!b[col[i][h].se]) {Cut(col[i][h].se);}
else {Link(col[i][h].se);}
b[col[i][h].se] ^= 1;
}
pre = ans;
del[col[i][j].fi] += ans;
j = t;
}
for(int j = 0 ; j < col[i].size() ; ++j) {
if(b[col[i][j].se]) {
b[col[i][j].se] = 0;
Link(col[i][j].se);
}
}
}
for(int i = 0 ; i <= M ; ++i) {
if(i) del[i] += del[i - 1];
out(1LL * N * N * N - del[i]);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
return 0;
}

【CodeForces】1172E. Nauuo and ODT的更多相关文章

  1. 【Codeforces】Round #491 (Div. 2) 总结

    [Codeforces]Round #491 (Div. 2) 总结 这次尴尬了,D题fst,E没有做出来.... 不过还好,rating只掉了30,总体来说比较不稳,下次加油 A:If at fir ...

  2. 【Codeforces】Round #488 (Div. 2) 总结

    [Codeforces]Round #488 (Div. 2) 总结 比较僵硬的一场,还是手速不够,但是作为正式成为竞赛生的第一场比赛还是比较圆满的,起码没有FST,A掉ABCD,总排82,怒涨rat ...

  3. 【CodeForces】601 D. Acyclic Organic Compounds

    [题目]D. Acyclic Organic Compounds [题意]给定一棵带点权树,每个点有一个字符,定义一个结点的字符串数为往下延伸能得到的不重复字符串数,求min(点权+字符串数),n&l ...

  4. 【Codeforces】849D. Rooter's Song

    [算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...

  5. 【CodeForces】983 E. NN country 树上倍增+二维数点

    [题目]E. NN country [题意]给定n个点的树和m条链,q次询问一条链(a,b)最少被多少条给定的链覆盖.\(n,m,q \leq 2*10^5\). [算法]树上倍增+二维数点(树状数组 ...

  6. 【CodeForces】925 C.Big Secret 异或

    [题目]C.Big Secret [题意]给定数组b,求重排列b数组使其前缀异或和数组a单调递增.\(n \leq 10^5,1 \leq b_i \leq 2^{60}\). [算法]异或 为了拆位 ...

  7. 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块

    [题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...

  8. 【CodeForces】906 D. Power Tower 扩展欧拉定理

    [题目]D. Power Tower [题意]给定长度为n的正整数序列和模数m,q次询问区间[l,r]累乘幂%m的答案.n,q<=10^5,m,ai<=10^9. [算法]扩展欧拉定理 [ ...

  9. 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    [题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...

随机推荐

  1. mac 安装rabbitmq出现的问题

    一直提示这个文件权限问题. 然后试了各种办法.chown user:group / chmod 777 等等.都没有解决. 最后查到 chmod 666 /users/xxx/.erlang.cook ...

  2. python3编程基础之一:注释模块和包

    1.注释 python中的注释和其他任何编程语言中的注释都不一样,有的注释有特殊要求,而是还是有用的. 1).单行注释:注释以#开始到语句结尾,#号后一般跟一个空格 2).多行注释:文档注释,以&qu ...

  3. Poseidon 系统是一个日志搜索平台——认证看链接ppt,本质是索引的倒排列表和原始日志数据都存在HDFS,而文档和倒排的元数据都在NOSQL里,同时针对单个filed都使用了独立索引,使用MR来索引和搜索

    Poseidon 系统是一个日志搜索平台,可以在百万亿条.100PB 大小的日志数据中快速分析和检索.360 公司是一个安全公司,在追踪 APT(高级持续威胁)事件,经常需要在海量的历史日志数据中检索 ...

  4. ngx.shared.DICT.set

    ngx.shared.DICT.set 原文: ngx.shared.DICT.set syntax: success, err, forcible = ngx.shared.DICT:set(key ...

  5. arcgis python 获得arcgis安装版本和安装位置

    import arcpy print(arcpy.GetInstallInfo()['Version']) 和获得ArcGIS版本和安装位置 import arcpy # Use the dictio ...

  6. pytest 基本用法

    1.断言用assert,可以进行==,!=,+,-,*,/,<=,>=,is True.False,is not True.False ,in ,not in 等判断. import py ...

  7. gis空间分析案例_7参数单坐标转换

    gis空间分析案例_7参数单坐标转换 商务科技合作:向日葵,135-4855__4328,xiexiaokui#qq.com 功能: 对输入的单个坐标,利用7参数,一步进行坐标变换,使用极为直观,极大 ...

  8. vue官网笔记

    学习了vue后又重新过了一遍官网的教程,选择性地摘抄了一些自己觉得比较重要的知识点.以备后面查缺补漏用. 计算属性 计算属性mounted中,属性值函数将用作属性的getter函数.当函数中的依赖发生 ...

  9. world: 对比两个文档

    1. 2. 3. 4.

  10. 强大全面的C++框架和库推荐!

    C++ 资源大全 关于 C++ 框架.库和资源的一些汇总列表,内容包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++标准库,包括了STL容器,算法和 ...