Codeforces Round #707 B - Napoleon Cake

今天打校赛打自闭了……

今天就水一下昨天的B题的另一种比较好的做法吧(#摸鱼)

明天再奋斗吧orz

首先思路还是差分标记区间之后再计算前缀和。

那么具体应该怎么做呢。

对于每一层,我们应该从该层向下渗透,找到渗透的最底层(如果渗透完了就是第1层)。然后令其值+1.再令该层的上面一层的值-1。

这样计算前缀和时。对于每一层的值需要加上他前面所有层。从最底下一层的值加上后一路向上都为1,一直加到上面一层的-1后为0,即该层未被渗透。

由于值可以大于1且-1有多个。故表示了多个区间。

例如样例中

6

0 3 0 0 1 3

的差分数组即为

1,0,-1,1,1,-1(下标从0开始)

AC代码如下:(照搬_onglu大佬的。心好累……呜呜呜)

#include <bits/stdc++.h>
#define Mid (l + r << 1)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
int read() {
    char c; int num, f = 1;
    while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0';
    while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
    return f * num;
}
const int N = 2e5 + 1009;
int n, a[N], f[N];
void work() {
    n = read();
    for(int i = 0; i <= n; i++) f[i] = 0;
    for(int i = 1; i <= n; i++) {
        a[i] = read();
        f[(i - a[i] + 1) > 0 ? (i - a[i] + 1) : 1] += 1;
        f[i + 1] -= 1;
    }
    for(int i = 1; i <= n; i++) {
        f[i] += f[i - 1];
        if(f[i] > 0) printf("1 ");
        else printf("0 ");
    }
    printf("\n");
}
signed main()
{
    int Case = read();
    while(Case--) work();
    return 0;
}

 

posted @ 2021-03-14 21:20  mikku  阅读(81)  评论(0)    收藏  举报