【YBT2022寒假Day1 A】变量观测(模拟)(分治)

变量观测

题目链接: YBT2022寒假Day1 A

题目大意

给你 n 个数,要你在线维护两种操作:
给一个数加一个值,或者设立一个观察者观察一些数,从当时开始观察,当观察的数的变化值的和大于一个设定值是结束观察。
然后对于每个加数的操作你要输出有多少个观察者结束观察。

思路

发现一个人监视的顶多三个人,我们考虑用这么一个神奇的方法。
(因为如果只能监视一个人我们可以直接用 set 模拟)

我们考虑把每个人的阀值设为 vkv 是权值,k 是监视的人数)

这有什么用呢,如果所有人都没有到达这个值,那就一定不会达到 v
那有一个到了之后,我们就可以从 set 中拿出来试一下。
如果可以就行,不可以的话,我们发现我们可以分剩下的数。

那每次至少减少 2/3 的量,那就是一个 log1.5v 的次数。
所以是可以的。

代码

#include<set> #include<cstdio> #define ll long long using namespace std; ll n, q, lst, x, y, z, a[200001], e[200001]; ll dy[200001][4], p, c[200001][4]; set <pair<ll, ll> > lim[200001]; set <ll> ans; void check(ll x) { ll tmp = e[x]; for (ll i = 1; i <= dy[x][0]; i++) { ll y = dy[x][i]; tmp -= a[y]; lim[y].erase(make_pair(c[x][i], x)); } if (tmp <= 0) { ans.insert(x); } else { for (ll i = 1; i <= dy[x][0]; i++) { ll y = dy[x][i]; c[x][i] = a[y] + (tmp + dy[x][0] - 1) / dy[x][0]; lim[y].insert(make_pair(c[x][i], x)); } } } int main() { // freopen("obs.in", "r", stdin); // freopen("obs.out", "w", stdout); scanf("%lld %lld", &n, &q); while (q--) { scanf("%lld %lld %lld", &x, &y, &z); if (x == 1) { y ^= lst; dy[++p][0] = z; e[p] = y; for (ll i = 1; i <= dy[p][0]; i++) { scanf("%lld", &z); z ^= lst; e[p] += a[z]; dy[p][i] = z; c[p][i] = (y + dy[p][0] - 1) / dy[p][0]; lim[z].insert(make_pair(c[p][i], p)); } } else { ans.clear(); y ^= lst; z ^= lst; a[y] += z; while (lim[y].size() && a[y] >= (*lim[y].begin()).first) { check((*lim[y].begin()).second); } lst = ans.size(); printf("%lld", lst); for (set <ll> ::iterator it = ans.begin(); it != ans.end(); it++) printf(" %lld", *it); printf("\n"); } } return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT2022Day1_A.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示