CF 2100-2400 data structures 乱做

CF2002E Cosmic Rays \(\star\)

顺着询问想增加二元组 \((a,b)\) 的影响。只需要考虑它的合并情况,即尾部什么时候会出现数字 \(b\),而总时间可以看作是最后一个尾部的存在时间,所以我们只需要关心尾部
用栈维护尾部的数值和存在时间(不难发现这是一个单调栈)

vector<pair<LL,int>> s;
For(i,1,n) {
	LL a, mx = 0; int b; cin>>a>>b;
	while( sz(s) && (a >= s.back().fi || b == s.back().se) ) {
		if( b == s.back().se ) a += s.back().fi - mx;
		else mx = s.back().fi;
		s.pop_back();
	}
	s.pb(a,b);
	cout<<s.front().fi<<" ";
}

CF2002D2 DFS Checker (Hard Version)

https://www.cnblogs.com/ft61/p/18402281

CF2000H Ksyusha and the Loaded Set

插入/删除只会影响 \(O(1)\) 个极长连续段。在极长连续段左端点处记录段长,线段树二分查询

需要注意一下初始化和清空

CF1998E1 Eliminating Balls With Merging (Easy Version)

题意等价于问有多少个 \(i\) 满足从 \(i\) 开始,若当前区间和 \(\ge\) 左边/右边的数就合并,能合并整个序列

考虑向左合并至左边的数 \(>\) 区间和(线段树二分 \(O(\log n)\) 实现),再向右合并,轮流进行。每切换两次都会使区间和翻倍,只会进行 \(O(\log a)\)

官方题解利用了“从 \(i\) 开始可行,从 \(j\) 开始能合并 \(i\Rightarrow j\) 可行”,值得一看

CF1998D Determine Winning Islands in Race

加速模拟是困难的,因为不可用的点会随走的次数增加

设 B 从点 \(i\) 开始,则 \(<i\) 的点永远可用(一定按最短路 \(dis\) 走)。考虑 L 超过 B 的那一步,L 赢 \(\iff\) 能从 \(<i\) 的点 \(u\) 走到 B 前面 \(\iff\exists(u,v)\in\mathbb{E}\) 使得 \(v>i+dis[u]+1\)
只需要维护 \(\max_{u<i,(u,v)\in\mathbb{E}}\{v-dis[u]\}\),时间复杂度 \(O(n)\)

CF1997E Level Up

容易做到 \(O(n\sqrt{n})\) 或者 \(O(n\log^2n)\)

考虑对每个 \(i\) 求出最小的 \(k\) 使得它不会 flee,记作 \(mn[i]\)
二分答案。\(i\) 会 flee \(\iff\) 前面至少打了 \(a[i]\cdot mid\)\(\boldsymbol{\iff a[i]\cdot mid\le\sum_{j<i}[mid\ge mn[j]]}\)

树状数组。时间复杂度 \(O(n\log a)\)

posted @ 2024-09-03 19:33  ft61  阅读(30)  评论(0)    收藏  举报