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)\)

浙公网安备 33010602011771号