灼之花好评,条条生日快乐(假装现在 8.15)!

\(\mathcal{Description}\)

  给定一棵以 \(1\) 为根的树,第 \(i\) 个结点有颜色 \(c_i\) 和光亮值 \(l_i\),定义树的权值为:

\[\sum_{\displaystyle u<v\land c_u=c_v\land\\\operatorname{LCA}(u,v)\not=u\land\operatorname{LCA}(u,v)\not=v}l_u\oplus l_v
\]

  现有 \(m\) 次修改,每次修改某点的颜色或光亮值,求出每次修改后树的权值。

  \(n,m\le10^5\),\(c_i\le n\),\(l_i<2^{20}\)。

\(\mathcal{Solution}\)

  分颜色贡献,位运算拆位,基本姿势 w!

  假定树的结点全部同色且光亮值为 \(0/1\),考虑点 \(u\) 的贡献,显然先加上所有能与它异或成 \(1\) 的结点个数,再减去在子树内或在祖先上的结点个数。而从动态修改的角度,两者都能使用 BIT(树状数组)维护!

  所以,枚举每个颜色 \(c\),对于每一个 bit,维护两个 BIT,分别保存子树内颜色为 \(c\) 且当前 bit 为 \(1\) 的结点个数和祖先上颜色为 \(c\) 且当前 bit 为 \(1\) 的结点个数,处理修改就暴力除去贡献再更新贡献即可。

  复杂度 \(\mathcal O(20(n+m)\log n)\)。

\(\mathcal{Code}\)

#include <cstdio>
#include <vector>
#include <iostream> typedef long long LL; inline char fgc () {
static char buf[1 << 17], *p = buf, *q = buf;
return p == q && ( q = buf + fread ( p = buf, 1, 1 << 17, stdin ), p == q ) ? EOF : *p ++;
} inline int rint () {
int x = 0; char s = fgc ();
for ( ; s < '0' || '9' < s; s = fgc () );
for ( ; '0' <= s && s <= '9'; s = fgc () ) x = x * 10 + ( s ^ '0' );
return x;
} inline void wint ( const LL x ) {
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} const int MAXN = 1e5;
int n, m, ecnt, head[MAXN + 5], col[MAXN + 5], val[MAXN + 5];
int dfc, dep[MAXN + 5], dfn[MAXN + 5], siz[MAXN + 5];
LL ans[MAXN + 5]; struct Edge { int to, nxt; } graph[MAXN * 2 + 5]; struct BinaryIndexTree {
int val[MAXN + 5];
inline int lowbit ( const int x ) { return x & -x; }
inline void update ( int x, const int k ) { for ( ; x <= n; x += lowbit ( x ) ) val[x] += k; }
inline int sum ( int x ) { int ret = 0; for ( ; x; x -= lowbit ( x ) ) ret += val[x]; return ret; }
inline int sum ( const int l, const int r ) { return sum ( r ) - sum ( l - 1 ); }
} facnt, soncnt, fabit[20], sonbit[20]; struct BitBucket {
int all, cnt[20];
inline void clear () { all = 0; for ( int i = 0; i < 20; ++ i ) cnt[i] = 0; }
inline void update ( const int x, const int k ) {
all += k;
for ( int i = 0; 1 << i <= x; ++ i ) {
if ( ( x >> i ) & 1 ) {
cnt[i] += k;
}
}
}
inline LL query ( const int x ) {
LL ret = 0;
for ( int i = 0; i < 20; ++ i ) {
if ( ( x >> i ) & 1 ) ret += 1ll * ( all - cnt[i] ) << i;
else ret += 1ll * cnt[i] << i;
}
return ret;
}
} buc; struct Event {
int u, val, time, type;
Event () {}
Event ( const int tu, const int tv, const int tti, const int tty ):
u ( tu ), val ( tv ), time ( tti ), type ( tty ) {}
}; std::vector<Event> evt[MAXN + 5]; inline void link ( const int s, const int t ) {
graph[++ ecnt].to = t, graph[ecnt].nxt = head[s];
head[s] = ecnt;
} inline void init ( const int u, const int f ) {
siz[u] = 1, dfn[u] = ++ dfc, dep[u] = dep[f] + 1;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ f ) {
init ( v, u ), siz[u] += siz[v];
}
}
} inline void initEvent () {
m = rint ();
for ( int i = 1; i <= n; ++ i ) evt[col[i]].push_back ( Event ( i, val[i], 0, 1 ) );
for ( int i = 1, op, u, t; i <= m; ++ i ) {
op = rint (), u = rint (), t = rint ();
evt[col[u]].push_back ( Event ( u, val[u], i, 0 ) );
if ( op & 1 ) evt[col[u] = t].push_back ( Event ( u, val[u], i, 1 ) );
else evt[col[u]].push_back ( Event ( u, val[u] = t, i, 1 ) );
}
for ( int i = 1; i <= n; ++ i ) evt[col[i]].push_back ( Event ( i, val[i], m + 1, 0 ) );
} inline LL queryFa ( const int u, const int val ) {
LL ret = 0;
int all = facnt.sum ( dfn[u] );
for ( int i = 0; i < 20; ++ i ) {
if ( ( val >> i ) & 1 ) ret += 1ll * ( all - fabit[i].sum ( dfn[u] ) ) << i;
else ret += 1ll * fabit[i].sum ( dfn[u] ) << i;
}
return ret;
} inline void updateFa ( const int u, const int val, const int k ) {
int l = dfn[u], r = dfn[u] + siz[u];
facnt.update ( l, k ), facnt.update ( r, -k );
for ( int i = 0; 1 << i <= val; ++ i ) {
if ( ( val >> i ) & 1 ) {
fabit[i].update ( l, k );
fabit[i].update ( r, -k );
}
}
} inline LL querySon ( const int u, const int val ) {
LL ret = 0;
int l = dfn[u], r = dfn[u] + siz[u] - 1;
int all = soncnt.sum ( l, r );
for ( int i = 0; i < 20; ++ i ) {
if ( ( val >> i ) & 1 ) ret += 1ll * ( all - sonbit[i].sum ( l, r ) ) << i;
else ret += 1ll * sonbit[i].sum ( l, r ) << i;
}
return ret;
} inline void updateSon ( const int u, const int val, const int k ) {
soncnt.update ( dfn[u], k );
for ( int i = 0; 1 << i <= val; ++ i ) {
if ( ( val >> i ) & 1 ) {
sonbit[i].update ( dfn[u], k );
}
}
} int main () {
freopen ( "cop.in", "r", stdin );
freopen ( "cop.out", "w", stdout );
n = rint ();
for ( int i = 1; i <= n; ++ i ) col[i] = rint ();
for ( int i = 1; i <= n; ++ i ) val[i] = rint ();
for ( int i = 1, u, v; i < n; ++ i ) {
u = rint (), v = rint ();
link ( u, v ), link ( v, u );
}
init ( 1, 0 ), initEvent ();
for ( int c = 1; c <= n; ++ c ) {
buc.clear ();
LL sum = 0, ill = 0;
for ( int i = 0; i ^ evt[c].size (); ++ i ) {
Event cur ( evt[c][i] );
if ( cur.type ) {
sum += buc.query ( cur.val ), buc.update ( cur.val, 1 );
ill += queryFa ( cur.u, cur.val ), updateFa ( cur.u, cur.val, 1 );
ill += querySon ( cur.u, cur.val ), updateSon ( cur.u, cur.val, 1 );
} else {
sum -= buc.query ( cur.val ), buc.update ( cur.val, -1 );
ill -= queryFa ( cur.u, cur.val ), updateFa ( cur.u, cur.val, -1 );
ill -= querySon ( cur.u, cur.val ), updateSon ( cur.u, cur.val, -1 );
}
if ( cur.time <= m ) {
ans[cur.time] += sum - ill;
ans[i + 1 == ( int ) evt[c].size () ? m + 1 : evt[c][i + 1].time] -= sum - ill;
}
}
}
wint ( ans[0] ), putchar ( '\n' );
for ( int i = 1; i <= m; ++ i ) printf ( "%lld", ans[i] += ans[i - 1] ), putchar ( '\n' );
return 0;
}

\(\mathcal{Details}\)

  考场上卡常 \(\mathcal O(n(m+\log n))\) 骗到 \(50pts\) 心满意足 www。

  这种类似离线的处理方法要感知到位,毕竟兔子这种码力持久化啊虚树啊都不可能考场敲出来 qwq(自暴自弃。

Solution -「LOCAL」Burning Flowers的更多相关文章

  1. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  2. Solution -「LOCAL」大括号树

    \(\mathcal{Description}\)   OurTeam & OurOJ.   给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...

  3. Solution -「LOCAL」过河

    \(\mathcal{Description}\)   一段坐标轴 \([0,L]\),从 \(0\) 出发,每次可以 \(+a\) 或 \(-b\),但不能越出 \([0,L]\).求可达的整点数. ...

  4. Solution -「LOCAL」Drainage System

    \(\mathcal{Description}\)   合并果子,初始果子的权值在 \(1\sim n\) 之间,权值为 \(i\) 的有 \(a_i\) 个.每次可以挑 \(x\in[L,R]\) ...

  5. Solution -「LOCAL」画画图

    \(\mathcal{Description}\)   OurTeam.   给定一棵 \(n\) 个点的树形随机的带边权树,求所有含奇数条边的路径中位数之和.树形生成方式为随机取不连通两点连边直到全 ...

  6. Solution -「LOCAL」ZB 平衡树

    \(\mathcal{Description}\)   OurOJ.   维护一列二元组 \((a,b)\),给定初始 \(n\) 个元素,接下来 \(m\) 次操作: 在某个位置插入一个二元组: 翻 ...

  7. Solution -「LOCAL」舟游

    \(\mathcal{Description}\)   \(n\) 中卡牌,每种三张.对于一次 \(m\) 连抽,前 \(m-1\) 次抽到第 \(i\) 种的概率是 \(p_i\),第 \(m\) ...

  8. Solution -「LOCAL」充电

    \(\mathcal{Description}\)   给定 \(n,m,p\),求序列 \(\{a_n\}\) 的数量,满足 \((\forall i\in[1,n])(a_i\in[1,m])\l ...

  9. Solution -「LOCAL」「cov. 牛客多校 2020 第五场 C」Easy

    \(\mathcal{Description}\)   Link.(完全一致)   给定 \(n,m,k\),对于两个长度为 \(k\) 的满足 \(\left(\sum_{i=0}^ka_i=n\r ...

随机推荐

  1. SCALA-基础知识学习(一)

    概述 本人开始学习scala的时候,是在使用和开发spark程序的时候,在此为了整理.记录和分享scala的基础知识,我写这篇关于scala的基础知识,希望与广大读者共同学习沟通进步.如果有些代码比较 ...

  2. JAVA自定义连接池原理设计(一)

    一,概述 本人认为在开发过程中,需要挑战更高的阶段和更优的代码,虽然在真正开发工作中,代码质量和按时交付项目功能相比总是无足轻重.但是个人认为开发是一条任重而道远的路.现在本人在网上找到一个自定义连接 ...

  3. 对飞猪H5端API接口sign签名逆向实验

    免责声明 本文章所提到的技术仅用于学习用途,禁止使用本文章的任何技术进行发起网络攻击.非法利用等网络犯罪行为,一切信息禁止用于任何非法用途.若读者利用文章所提到的技术实施违法犯罪行为,其责任一概由读者 ...

  4. leetcode 1021. 删除最外层的括号

    问题描述 有效括号字符串为空 ("")."(" + A + ")" 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的 ...

  5. python极简教程08:对象的方法

    测试奇谭,BUG不见. 讲解之前,我先说说我的教程和网上其他教程的区别: 1 我分享的是我在工作中高频使用的场景,是精华内容: 2 我分享的是学习方法,亦或说,是指明你该学哪些.该重点掌握哪些内容: ...

  6. Rust 连接 PostgreSQL 数据库

    这次,我们使用 postgres 这个 crate 来连接和操作 PostgreSQL 数据库. 创建好项目后,在 cargo.toml 里添加 postgres 的依赖: 首先,导入相关的类型,并创 ...

  7. Qt之简单绘图实现

    效果图:                                              可以实现打开图片,在打开的图片上画图,可以保存图片,以及橡皮擦,画笔调大调粗换色功能. 代码: XI ...

  8. gin框架中HTTP请求和参数的解析

    1. 方法一: 通用的处理方法---Handle package main import ( "fmt" "github.com/gin-gonic/gin" ...

  9. 自动化部署:在Windows平台安装Jenkins

    在软件开发中经常会提到持续集成Continuous Integration(CI)和持续交付Continuous Delivery(CD).其中Jenkins是一个开源软件项目,是基于Java开发的一 ...

  10. 大厂面试:一个四年多经验程序员的BAT面经(字节、阿里、腾讯)

    前言 上次写了篇欢聚时代的面经,公众号后台有些读者反馈说看的意犹未尽,希望我尽快更新其他大厂的面经,这里先说声抱歉,不是我太懒,而是项目组刚好有个活动要赶在春节前上线,所以这几天经常加班,只能工作之余 ...