20221005多校联训

T1 CF1252G Performance Review

一个公司有 n 个员工,每个员工有一个能力值 ai, 每个 ai 都不一样。公司采取末位淘汰制,我们考虑 m 年,每年年底都会补充 ri 个新员工,每个新员工的能力值被表示为 bij, 即第 i 年新加入的第 j 个员工的能力值。每年,能力值最靠后的 ri 个员工会被炒鱿鱼,取而代之的是新加入的这 ri 个员工。你是第 1 号员工,你的能力值是 a1
还有 q 次操作,每次操作的描述形如 (xi,yi,zi), 表示把第 xi 年加入的第 yi 个员工的能力值改为 zi。 现在对于每个操作输出 01,表示如果进行完这个操作,m 年之后你会不会被炒鱿鱼。注意,操作是永久性的。

注意到,对于当前数列中的所有数,可以简单地将它们分为两类,即大于 a1 的一类和小于 a1 这一类。这两类数决定了 a1 在当前数列中的排名,影响着它是否会被炒鱿鱼。

那么,我们只需要关注每个时刻数列中比 a1 小的数的个数和当前时刻会炒多少人的鱿鱼的关系。如果前者小于后者,那么就会被炒鱿鱼。

题目中还有修改操作,对于第 x 年某个值的修改操作可能会影响到 [x,m] 这个范围年份中比 a1 小的数的数量。显然这是一个区间修改操作,考虑用线段树来维护 ai 的排名。

对于一次修改,如果修改之前的数小于 a1,且修改后的数大于 a1,那么在 x 年后,比 a1 小的数的数量都减一。反之,如果修改之前的数大于 a1,且修改之后的数小于 a1,那么在 x 年后,比 a1 小的数的数量都加一。令第 k 年比 a1小的数的数量为 p[k]。我们在线段树中还应该记录一个 p[k]r[k] 的最小值 mn。如果在整个区间中,mn 的最小值小于 0,那么你就会被开除,反之则不会。

代码:

#include<bits/stdc++.h> #define ll (i<<1) #define rr (i<<1) + 1 #define mid (tl + tr) / 2 using namespace std; const int MAXN = 1e5; int n,m,a[MAXN + 5],q; vector<int> ins[MAXN + 5]; int cnt; struct node{ int lazy,num,mn; }tree[MAXN * 4 + 20]; void build(int i,int tl,int tr){ if(tl == tr){ tree[i].num = cnt; return; } build(ll,tl,mid); build(rr,mid + 1,tr); } void push_down(int i){ tree[ll].lazy += tree[i].lazy; tree[rr].lazy += tree[i].lazy; tree[ll].mn += tree[i].lazy; tree[rr].mn += tree[i].lazy; tree[i].lazy = 0; } void change(int i,int tl,int tr,int l,int r,int k){ if(tl > r || tr < l)return; if(tl >= l && tr <= r){ tree[i].mn += k; tree[i].lazy += k; return; } push_down(i); change(ll,tl,mid,l,r,k); change(rr,mid + 1,tr,l,r,k); tree[i].mn = min(tree[ll].mn,tree[rr].mn); } int b[MAXN + 5]; int query(int i,int tl,int tr,int p){ if(tl == tr){ tree[i].num += tree[i].lazy; tree[i].lazy = 0; tree[i].mn = tree[i].num - b[tl]; return tree[i].num; } push_down(i); int ans; if(p > mid)ans = query(rr,mid + 1,tr,p); else ans = query(ll,tl,mid,p); tree[i].mn = min(tree[ll].mn,tree[rr].mn); } int main(){ // freopen("a3.in","r",stdin); // freopen("ans","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m >> q; for(int i = 1; i <= n; i++){ cin >> a[i]; if(i != 1 && a[i] < a[1])cnt++; } build(1,1,m); for(int i = 1; i <= m;i++){ cin >> b[i]; int c; cnt = 0; for(int j = 1; j <= b[i];j++){ cin >> c; ins[i].push_back(c); if(c < a[1])cnt++; } int p = query(1,1,m,i); c = cnt - b[i]; change(1,1,m,i + 1,m,c); } for(int i = 1; i <= m; i++)int p = query(1,1,m,i); int x,y,z; int now = 1; for(int i = 1; i <= q; i++){ cin >> x >> y >> z; if(ins[x][y - 1] < a[1] && z > a[1])change(1,1,m,x + 1,m,-1); else if(ins[x][y - 1] > a[1] && z < a[1])change(1,1,m,x + 1,m,1); bool flag = 0; int k = query(1,1,m,1); k = query(1,1,m,m); if(tree[1].mn < 0)cout << "0\n"; else cout << "1\n"; ins[x][y - 1] = z; } } //5 3 3 //50 40 30 20 10 //4 1 2 3 100 //1 4 //2 6 7 //1 3 300 //2 1 400 //2 1 52

__EOF__

本文作者Never Gonna Give You Up!
本文链接https://www.cnblogs.com/CZ-9/p/16758078.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   腾云今天首飞了吗  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示