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; }

浙公网安备 33010602011771号