CodeForces - 1252G Performance Review (线段树)

题目:

Randall is a software engineer at a company with NN employees. Every year, the company re-evaluates its employees. At the end of every year, the company replaces its several worst-performing employees and replaces with the same number of new employees, so that the company keeps having NN employees. Each person has a constant performance and can be represented by an integer (higher integer means better performance), and no two people have the same performance.

The performance of the initial employees are represented by an array of integers A=[A1,A2,,AN]A=[A1,A2,…,AN] where AiAi is the performance of the ithith employee. Randall is employee 11, so his performance is A1A1. We will consider the first MM years. At the end of the ithith year, the company replaces its RiRi worst-performing employees and replaces with RiRi new employees. The performance of these new employees are represented by an array of integers Bi=[(Bi)1,(Bi)2,,(Bi)Ri]Bi=[(Bi)1,(Bi)2,…,(Bi)Ri] where (Bi)j(Bi)j is the performance of the jthjth new employee.

He will consider QQ scenarios. On the ithith scenario, he will change the value of (BXi)Yi(BXi)Yi to ZiZi. For each scenario, Randall is wondering whether he will still be in the company after MM years. Note that the changes in each scenario are kept for the subsequent scenarios.

Input

Input begins with a line containing three integers: NMQQ (2N1000002≤N≤100000; 1M,Q1000001≤M,Q≤100000) representing the number of employees, the number of years to be considered, and the number of scenarios, respectively. The next line contains NN integers: AiAi (0Ai1090≤Ai≤109) representing the performance of the initial employees. The next MM lines each contains several integers: RiRi (Bi)1(Bi)1, (Bi)2(Bi)2, ⋯, (Bi)Ri(Bi)Ri (1Ri<N1≤Ri<N; 0(Bi)j1090≤(Bi)j≤109) representing the number of employees replaced and the performance of the new employees, respectively. It is guaranteed that the sum of RiRi does not exceed 106106. The next QQ lines each contains three integers: XiXi YiYi ZiZi (1XiM1≤Xi≤M; 1YiR(Xi)1≤Yi≤R(Xi); 0Zi1090≤Zi≤109) representing a scenario. It is guaranteed that all integers in all AiAi, (Bi)j(Bi)j, and ZiZi (combined together) are distinct.

Output

For each scenario in the same order as input, output in a line an integer 00 if Randall will not be in the company after MM years, or 11 if Randall will still be in the company after MM years.

Example

Input
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 5
Output
1
0
1

Note

Explanation for the sample input/output #1

Randall performance is represented by 5050. For the first scenario, the value of (B1)3(B1)3 is updated to 300300, causes the following:

  • Initially, the performance of the employees is [50,40,30,20,10][50,40,30,20,10].
  • At the end of the first year, 44 worst-performing employees are replaced by employees with performance [300,100,2,1][300,100,2,1]. Therefore, the performance of the employees is [300,100,50,2,1][300,100,50,2,1].
  • At the end of the second year, the performance of the employees is [300,100,50,4,2][300,100,50,4,2].
  • At the end of the third year, the performance of the employees is [300,100,50,7,6][300,100,50,7,6].

Therefore, Randall will still be in the company after 33 years.

 

For the second scenario, the value of (B2)1(B2)1 is updated to 400400, causes the following:

  • Initially, the performance of the employees is [50,40,30,20,10][50,40,30,20,10].
  • At the end of the first year, the performance of the employees is [300,100,50,2,1][300,100,50,2,1]. Recall that the change in the first scenario is kept for this scenario as well.
  • At the end of the second year, the performance of the employees is [400,300,100,50,2][400,300,100,50,2].
  • At the end of the third year, the performance of the employees is [400,300,100,7,6][400,300,100,7,6].

Therefore, Randall will not be in the company after 33 years.

题意:

  一个公司一开始有n个人,每个人都有自己的绩效(下面用数值代替),题目保证每个人的数值都不一样,第i天开除数值最低的Ri个人,并引入相同个数的人,每个人同样有自己的数值。Q组询问,每次询问三个参数x,y,z,表示把第x天引入的第y个人的数值改成z,问一开始的第一个人会不会被开除,会被开除的话输出0,否则输出1.

思路:

  我们需要维护一下相对大小的关系,这里我只维护数值比第一个人小的人数。(第一个人的数值用a[1]表示)

  首先要观察到,什么情况第一个人会被开除,第几天会被开除。假设第i天会被开除,那肯定是(第i-1天能力比a[1]小的人数)- (第i天开除的人)< 0 .........①

  显然第i天开除的人数是固定的,每组询问只会改变(第i天能力比a[1]小的人数),

  而(第i天能力比a[1]小的人数)=(第i-1天能力比a[1]小的人数)- (第i天开除的人数) + (第i天引入的数值小于a[i]的人数)........②

  ②式对比①式,发现多的部分是(第i天引入的数值小于a[i]的人数),询问修改的也是这个部分。

  设(第i天能力比a[1]小的人数)= ans[i]

  则 ans[i] = ans[i-1] - 第i天开除人数(定值)+x1

  ans[i+1] = ans[i] - 第i+1天开除人数(定值)+x2 = ans[i-1] - 第i天开除人数(定值)+x1 - 第i+1天开除人数(定值)+x2

  可以看出如果x1发生变化,那么他会影响ans[i]到ans[m],也就是区间修改。

  为了方便统计,定义线段树维护的数组ans[i] = (第i-1天能力比a[1]小的人数)- (第i天开除的人),这样修改x1的话影响的范围就是[i+1,m]。

  线段树维护区间最小值即可。

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 7;
vector<int> b[maxn];
int n,m,q,a[maxn],di[maxn],tr[maxn<<3],lz[maxn<<3],x,y,z;
void pushdown(int rt) {
    if(lz[rt]!=0) {
        tr[rt] += lz[rt];
        lz[rt<<1] += lz[rt];
        lz[rt<<1|1] += lz[rt];
        lz[rt] = 0;
    }
}
void build(int l,int r,int rt) {
    if(l == r) {
        tr[rt] = di[l];
        return;
    }
    int mid = l + r >> 1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    tr[rt] = min(tr[rt<<1],tr[rt<<1|1]);
}
void update(int l,int r,int rt,int L,int R,int c) {
    pushdown(rt);
    if(L<=l && r <= R) {
        lz[rt] += c;
        return;
    }
    int mid = l + r >> 1;
    if(L<=mid) update(l,mid,rt<<1,L,R,c);
    if(mid<R) update(mid+1,r,rt<<1|1,L,R,c);
    if(l!=r) {
        pushdown(rt<<1);
        pushdown(rt<<1|1);
        tr[rt] = min(tr[rt<<1],tr[rt<<1|1]);
    }
}
int main() {
    scanf("%d%d%d",&n,&m,&q);
    for (int i=1; i<=n; ++i) {
        scanf("%d",&a[i]);
        if(a[i] < a[1]) di[0]++;
    }
    int tmp = 0;
    for (int i=1; i<=m; ++i) {
        di[i] = di[i-1] + tmp;
        tmp = 0;
        scanf("%d",&x);
        di[i] -= x;
        for (int j=1; j<=x; ++j) {
            scanf("%d",&y);
            b[i].push_back(y);
            if(y < a[1]) tmp++;
        }
    }
    build(1,m,1);
    while(q--) { 
        scanf("%d%d%d",&x,&y,&z);
        if(b[x][y-1]<a[1] && a[1]<z) 
            update(1,m,1,x+1,m,-1);
        else if(b[x][y-1]>a[1] && a[1]>z)
            update(1,m,1,x+1,m,1);
        b[x][y-1] = z;
        if(tr[1]<0) printf("0\n");
        else printf("1\n");
    }
    return 0;
}

 

posted @ 2021-03-13 22:04  丿不落良辰  阅读(67)  评论(0编辑  收藏  举报