一个公司有 个员工,每个员工有一个能力值 , 每个 都不一样。公司采取末位淘汰制,我们考虑 年,每年年底都会补充 个新员工,每个新员工的能力值被表示为 , 即第 年新加入的第 个员工的能力值。每年,能力值最靠后的 个员工会被炒鱿鱼,取而代之的是新加入的这 个员工。你是第 号员工,你的能力值是 。
还有 次操作,每次操作的描述形如 , 表示把第 年加入的第 个员工的能力值改为 。 现在对于每个操作输出 或 ,表示如果进行完这个操作, 年之后你会不会被炒鱿鱼。注意,操作是永久性的。
注意到,对于当前数列中的所有数,可以简单地将它们分为两类,即大于 的一类和小于 这一类。这两类数决定了 在当前数列中的排名,影响着它是否会被炒鱿鱼。
那么,我们只需要关注每个时刻数列中比 小的数的个数和当前时刻会炒多少人的鱿鱼的关系。如果前者小于后者,那么就会被炒鱿鱼。
题目中还有修改操作,对于第 年某个值的修改操作可能会影响到 这个范围年份中比 小的数的数量。显然这是一个区间修改操作,考虑用线段树来维护 的排名。
对于一次修改,如果修改之前的数小于 ,且修改后的数大于 ,那么在 年后,比 小的数的数量都减一。反之,如果修改之前的数大于 ,且修改之后的数小于 ,那么在 年后,比 小的数的数量都加一。令第 年比 小的数的数量为 。我们在线段树中还应该记录一个 的最小值 。如果在整个区间中, 的最小值小于 ,那么你就会被开除,反之则不会。
代码:
#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(){
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;
}
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具