Solution -「LOCAL」模板
\(\mathcal{Description}\)
给定一棵 \(n\) 个结点树,\(1\) 为根,每个 \(u\) 结点有容量 \(k_u\)。\(m\) 次操作,每次操作 \((u,c)\),表示在 \(u\) 到根路径上的每个结点放一个颜色为 \(c\) 的小球,但若某一结点容量已满,则跳过该结点不放球。求所有操作完成后每个结点拥有小球的颜色种数。
\(n,m\le10^5\)。
\(\mathcal{Solution}\)
优雅的离线算法。
  首先,若 \((\forall u)(k_u\ge m)\),有一个很显然的 DFN(虚树)+差分+BIT 的计算方法,且这种计算可以通过 std::set 做到在线。现在考虑 \(k_u\) 的限制,我们可以在每个结点的球数刚好达到限制时对它询问求到答案,即利用整体二分把每个点的询问挂到一个操作时刻之后,就做完啦。
复杂度 \(\mathcal O(m(\log m)(\log n))\)。
\(\mathcal{Code}\)
/* Clearink */
#include <set>
#include <cstdio>
#include <vector>
#include <algorithm>
inline int rint () {
	int x = 0, f = 1; char s = getchar ();
	for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
	return x * f;
}
template<typename Tp>
inline void wint ( Tp x ) {
	if ( x < 0 ) putchar ( '-' ), x = -x;
	if ( 9 < x ) wint ( x / 10 );
	putchar ( x % 10 ^ '0' );
}
const int MAXN = 1e5, MAXLG = 17;
int n, m, ecnt, head[MAXN + 5], vol[MAXN + 5], tmpc[MAXN + 5], ans[MAXN + 5];
int dfc, dfn[MAXN + 5], ref[MAXN + 5], dep[MAXN + 5], siz[MAXN + 5];
int stc, stn[MAXN + 5], st[2 * MAXN + 5][MAXLG + 5], lg2[MAXN * 2 + 5];
std::vector<int> pts, qry[MAXN + 5];
std::set<int> vtr[MAXN + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
struct Event { int u, c; } evt[MAXN + 5];
struct BinaryIndexTree {
	int val[MAXN + 5];
	inline void update ( int x, const int k ) {
		for ( ; x <= n; x += x & -x ) {
			val[x] += k;
		}
	}
	inline int sum ( int x ) {
		int ret = 0;
		for ( ; x; x -= x & -x ) ret += val[x];
		return ret;
	}
	inline int sum ( const int l, const int r ) {
		return l > r ? 0 : sum ( r ) - sum ( l - 1 );
	}
} bit;
inline void link ( const int s, const int t ) {
	graph[++ ecnt] = { t, head[s] };
	head[s] = ecnt;
}
inline void init ( const int u, const int f ) {
	ref[dfn[u] = ++ dfc] = u;
	st[stn[u] = ++ stc][0] = u;
	siz[u] = 1, 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], st[++ stc][0] = u;
		}
	}
}
inline void initST () {
	for ( int i = 2; i <= stc; ++ i ) lg2[i] = lg2[i >> 1] + 1;
	for ( int j = 1; 1 << j <= stc; ++ j ) {
		for ( int i = 1; i + ( 1 << j ) - 1 <= stc; ++ i ) {
			if ( dep[st[i][j - 1]] < dep[st[i + ( 1 << j >> 1 )][j - 1]] ) {
				st[i][j] = st[i][j - 1];
			} else {
				st[i][j] = st[i + ( 1 << j >> 1 )][j - 1];
			}
		}
	}
}
inline int LCA ( int u, int v ) {
	if ( ( u = stn[u] ) > ( v = stn[v] ) ) u ^= v ^= u ^= v;
	int k = lg2[v - u + 1];
	return dep[st[u][k]] < dep[st[v - ( 1 << k ) + 1][k]] ?
		st[u][k] : st[v - ( 1 << k ) + 1][k];
}
inline void markQ ( std::vector<int>& pts, const int l, const int r ) {
	if ( pts.empty () ) return ;
	if ( l == r ) {
		for ( int u: pts ) qry[l].push_back ( u );
		return pts.clear ();
	}
	int mid = l + r >> 1;
	for ( int i = l ? l : 1; i <= mid; ++ i ) bit.update ( dfn[evt[i].u], 1 );
	std::vector<int> lc, rc;
	for ( int u: pts ) {
		if ( bit.sum ( dfn[u], dfn[u] + siz[u] - 1 ) < vol[u] ) rc.push_back ( u );
		else lc.push_back ( u );
	}
	pts.clear ();
	markQ ( rc, mid + 1, r );
	for ( int i = l ? l : 1; i <= mid; ++ i ) bit.update ( dfn[evt[i].u], -1 );
	markQ ( lc, l, mid );
}
inline void addNode ( std::set<int>& vtr, const int u ) {
	auto ret ( vtr.insert ( dfn[u] ) );
	if ( !ret.second ) return ;
	bit.update ( dfn[u], 1 );
	auto it ( ret.first ); int p = -1, q = -1;
	if ( it != vtr.begin () ) {
		bit.update ( dfn[LCA ( p = ref[*-- it], u )], -1 );
		++ it;
	}
	if ( ++ it != vtr.end () ) {
		bit.update ( dfn[LCA ( q = ref[*it], u )], -1 );
	}
	if ( ~p && ~q ) {
		bit.update ( dfn[LCA ( p, q )], 1 );
	}
}
int main () {
	freopen ( "ac.in", "r", stdin );
	freopen ( "ac.out", "w", stdout );
	n = rint ();
	for ( int i = 1, u, v; i < n; ++ i ) {
		u = rint (), v = rint ();
		link ( u, v ), link ( v, u );
	}
	for ( int i = 1; i <= n; ++ i ) {
		vol[i] = rint ();
		pts.push_back ( i );
	}
	m = rint ();
	for ( int i = 1; i <= m; ++ i ) {
		evt[i].u = rint (), tmpc[i] = evt[i].c = rint ();
	}
	std::sort ( tmpc + 1, tmpc + m + 1 );
	int mxc = std::unique ( tmpc + 1, tmpc + m + 1 ) - tmpc - 1;
	for ( int i = 1; i <= m; ++ i ) {
		evt[i].c = std::lower_bound ( tmpc + 1, tmpc + mxc + 1, evt[i].c ) - tmpc;
	}
	init ( 1, 0 ), initST ();
	markQ ( pts, 0, m );
	for ( int i = 1; i <= m; ++ i ) {
		addNode ( vtr[evt[i].c], evt[i].u );
		for ( int u: qry[i] ) ans[u] = bit.sum ( dfn[u], dfn[u] + siz[u] - 1 );
	}
	for ( int q = rint (); q --; ) wint ( ans[rint ()] ), putchar ( '\n' );
	return 0;
}
\(\mathcal{Details}\)
这题 Tricks 好多啊 owo。
Solution -「LOCAL」模板的更多相关文章
- Solution -「LOCAL」二进制的世界
		
\(\mathcal{Description}\) OurOJ. 给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...
 - Solution -「LOCAL」大括号树
		
\(\mathcal{Description}\) OurTeam & OurOJ. 给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...
 - Solution -「LOCAL」过河
		
\(\mathcal{Description}\) 一段坐标轴 \([0,L]\),从 \(0\) 出发,每次可以 \(+a\) 或 \(-b\),但不能越出 \([0,L]\).求可达的整点数. ...
 - Solution -「LOCAL」Drainage System
		
\(\mathcal{Description}\) 合并果子,初始果子的权值在 \(1\sim n\) 之间,权值为 \(i\) 的有 \(a_i\) 个.每次可以挑 \(x\in[L,R]\) ...
 - Solution -「LOCAL」Burning Flowers
		
灼之花好评,条条生日快乐(假装现在 8.15)! \(\mathcal{Description}\) 给定一棵以 \(1\) 为根的树,第 \(i\) 个结点有颜色 \(c_i\) 和光亮值 ...
 - Solution -「LOCAL」画画图
		
\(\mathcal{Description}\) OurTeam. 给定一棵 \(n\) 个点的树形随机的带边权树,求所有含奇数条边的路径中位数之和.树形生成方式为随机取不连通两点连边直到全 ...
 - Solution -「LOCAL」ZB 平衡树
		
\(\mathcal{Description}\) OurOJ. 维护一列二元组 \((a,b)\),给定初始 \(n\) 个元素,接下来 \(m\) 次操作: 在某个位置插入一个二元组: 翻 ...
 - Solution -「LOCAL」舟游
		
\(\mathcal{Description}\) \(n\) 中卡牌,每种三张.对于一次 \(m\) 连抽,前 \(m-1\) 次抽到第 \(i\) 种的概率是 \(p_i\),第 \(m\) ...
 - Solution -「LOCAL」充电
		
\(\mathcal{Description}\) 给定 \(n,m,p\),求序列 \(\{a_n\}\) 的数量,满足 \((\forall i\in[1,n])(a_i\in[1,m])\l ...
 
随机推荐
- Python常用功能函数系列总结(六)
			
本节目录 常用函数一:词云图 常用函数二:关键词清洗 常用函数三:中英文姓名转换 常用函数四:去除文本中的HTML标签和文本清洗 常用函数一:词云图 wordcloud # -*- coding: ...
 - Jeesite富文本编辑框ckeditor显示错误
			
Jeesite富文本编辑框ckeditor显示错误 原文链接:https://www.toutiao.com/i6485135618190869005/ Jeesite中Control都会继承一个Ba ...
 - 移动端调试 - UC浏览器开发者版 - WIFI
			
Chrome 功能特性 支持PC或Pad设备,实时调试手机网页 DOM.CSS.JS调试 多功能面板满足多种调试需求 1 准备工作 保证手机与PC处于同一个无线网段. 下载Android平台的U ...
 - lvgl移植—Linux fbdev&evdev(基于LVGL v7)
			
虽然lvgl官方提供了有关linux framebuffer操作的库函数,但是我决定自己试一下能否自己实现这部分操作 实际项目中应优先采用官方库函数,官方实现代码位于文件夹lv_drivers/dis ...
 - JUC之文章整理以及汇总
			
JUC文章汇总 JUC部分将学习<JUC并发编程的艺术>和<尚硅谷-大厂必备技术之JUC并发编程>进行博客的整理,各文章中也会不断的完善和丰富. JUC概述 JUC的视频学习和 ...
 - insert语句
			
7.4.插入数据insert(DML语句) 语法格式: insert into 表名(字段名1,字段名2,字段名3...) values(值1,值2,值3): 注意:字段名和值要一一对应.什么是一一对 ...
 - java-异常-自定义异常异常类的抛出throws
			
1 package p1.exception; 2 /* 3 * 对于角标是整数不存在,可以用角标越界表示, 4 * 对于负数为角标的情况,准备用负数角标异常来表示. 5 * 6 * 负数角标这种异常 ...
 - 进程(守护进程--互斥锁--IPC机制--生产者模型--僵尸进程与孤儿进程--模拟抢票--消息队列)
			
目录 一:进程理论知识 1.理论知识 二:什么是进程? 三:僵尸进程与孤儿进程 1.僵尸进程 四:守护进程 1.什么是守护进程? 2.主进程创建守护进程 3.守护进程 五:互斥锁(模拟多人抢票) 1. ...
 - ES_AutoCheck.sh
			
#!/bin/bash #@es_check #@date 2019/11/26 #@auth tigergao status=`curl -s GET "http://172.16.71. ...
 - [luoguP4139]上帝与集合的正确用法
			
\(\text{Description}\) \(\text{Given a number }p(p\leqslant10^7).\) \(\text{Output }2^{2^{2^{2^{\cdo ...