双指针大法好!!!
将数组扫一遍,每次找到相邻两个$0$位置, $0_1$的下标记为lst
($last$),$0_2$的下标记为cur
($current$),将$[lst, cur]$这个区间的中点的下标记为mid
.
对于每个$i$ $(lst < i \le mid)$,$b_i = i - lst$.
对于每个$j$ $(mid < j \le cur)$,$b_j = cur - j$.
边界情况: 当最后一个$cur$找不到时 ($a_i != 0$, $lst \le i \le n$), 将$b_j$标记为$j - lst$ $(lst \le j \le cur)$.
Code:
#include <cstdio>
const int N = 2e5 + 10;
int n, a[N], b[N], lst = -N, cur;
int main ()
{
scanf ("%d", &n);
for (int i = 1; i <= n; ++i) scanf ("%d", &a[i]);
for (int i = 1; i <= n; ++i)
{
for (int j = i; j <= n; ++j)
if (!a[cur = j]) break;
if (!a[cur])
for (int j = i; j <= cur; ++j) b[j] = j <= lst + cur >> 1 ? j - lst : cur - j;
else
{
for (int j = i; j <= n; ++j) b[j] = j - lst;
break;
}
lst = cur, i = lst;
}
for (int i = 1; i <= n; ++i) printf ("%d ", b[i]);
return 0;
}
终极卡常版: $113ms$
#include <cstdio>
#include <cmath>
#pragma GCC target ("avx,sse2,sse3,sse4,mmx")
#pragma GCC optimize (2)
#pragma GCC optimize (3)
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("inline")
#pragma GCC optimize ("-fgcse")
#pragma GCC optimize ("-fgcse-lm")
#pragma GCC optimize ("-fipa-sra")
#pragma GCC optimize ("-ftree-pre")
#pragma GCC optimize ("-ftree-vrp")
#pragma GCC optimize ("-fpeephole2")
#pragma GCC optimize ("-ffast-math")
#pragma GCC optimize ("-fsched-spec")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("-falign-jumps")
#pragma GCC optimize ("-falign-loops")
#pragma GCC optimize ("-falign-labels")
#pragma GCC optimize ("-fdevirtualize")
#pragma GCC optimize ("-fcaller-saves")
#pragma GCC optimize ("-fcrossjumping")
#pragma GCC optimize ("-fthread-jumps")
#pragma GCC optimize ("-funroll-loops")
#pragma GCC optimize ("-fwhole-program")
#pragma GCC optimize ("-freorder-blocks")
#pragma GCC optimize ("-fschedule-insns")
#pragma GCC optimize ("inline-functions")
#pragma GCC optimize ("-ftree-tail-merge")
#pragma GCC optimize ("-fschedule-insns2")
#pragma GCC optimize ("-fstrict-aliasing")
#pragma GCC optimize ("-fstrict-overflow")
#pragma GCC optimize ("-falign-functions")
#pragma GCC optimize ("-fcse-skip-blocks")
#pragma GCC optimize ("-fcse-follow-jumps")
#pragma GCC optimize ("-fsched-interblock")
#pragma GCC optimize ("-fpartial-inlining")
#pragma GCC optimize ("no-stack-protector")
#pragma GCC optimize ("-freorder-functions")
#pragma GCC optimize ("-findirect-inlining")
#pragma GCC optimize ("-fhoist-adjacent-loads")
#pragma GCC optimize ("-frerun-cse-after-loop")
#pragma GCC optimize ("inline-small-functions")
#pragma GCC optimize ("-finline-small-functions")
#pragma GCC optimize ("-ftree-switch-conversion")
#pragma GCC optimize ("-foptimize-sibling-calls")
#pragma GCC optimize ("-fexpensive-optimizations")
#pragma GCC optimize ("-funsafe-loop-optimizations")
#pragma GCC optimize ("inline-functions-called-once")
#pragma GCC optimize ("-fdelete-null-pointer-checks")
const int N = 2e5 + 10;
int n, a[N], b[N], lst = -N, cur;
namespace IO
{
#define DECIMAL 6
#define BUF_SIZE 400010
#define LL long long
char obuf[BUF_SIZE], *p3 = obuf;
inline char gc () { static char buf[BUF_SIZE], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, BUF_SIZE, stdin), p1 == p2) ? EOF : *p1++; }
inline void pc (char x) { (p3 - obuf < (1 << 31)) ? (*p3++ = x) : (fwrite (obuf, p3 - obuf, 1, stdout), p3 = obuf, *p3++ = x); }
inline void read (char &ch) { ch = gc (); }
inline void read (char s[]) { char ch = gc (); while (ch != ' ' && ch != '\n') *s++ = ch, ch = gc (); }
inline void read (int &x) { x = 0; bool f = 0; char ch = gc (); while (ch < '0' || ch > '9') f |= ch == '-', ch = gc (); while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + (ch ^ 48), ch = gc (); x = f ? ~x + 1 : x; }
inline void read (long long &x) { x = 0; bool f = 0; char ch = gc (); while (ch < '0' || ch > '9') f |= ch == '-', ch = gc (); while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + (ch ^ 48), ch = gc (); x = f ? ~x + 1 : x; }
inline void read (double &x) { x = 0; bool f = 0; char ch = gc (); while (ch < '0' || ch > '9') f |= ch == '-', ch = gc (); while (ch >= '0' && ch <= '9') x = (x * 10) + (ch ^ 48), ch = gc (); if (ch == '.') { double tmp = 1; ch = getchar(); while(ch >= '0' && ch <= '9') tmp /= 10.0, x += tmp * (ch ^ 48), ch = gc (); } x = f ? -x : x; }
inline void write (char ch) { pc (ch); }
inline void write (char s[]) { while (*s) pc (*s++); }
inline void write (int x) { static char c[11]; unsigned p = 0; if (x < 0) pc ('-'), x = ~x + 1; if (!x) { pc ('0'); return ; } while (x) c[++p] = x % 10 ^ 48, x /= 10; while (p) pc (c[p]), --p; }
inline void write (long long x) { static char c[20]; unsigned p = 0; if (x < 0) pc ('-'), x = ~x + 1; if (!x) { pc ('0'); return ; } while (x) c[++p] = x % 10 ^ 48, x /= 10; while (p) pc (c[p]), --p; }
inline void write (double x, int y = DECIMAL) { static LL mul[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000LL, 100000000000LL, 1000000000000LL, 10000000000000LL, 100000000000000LL, 1000000000000000LL, 10000000000000000LL, 100000000000000000LL}; if (x < -1e-12) pc ('-'), x = -x; x *= mul[y]; LL x1 = (LL) floor (x); if (floor (x) >= 0.5) ++x1; LL x2 = x1 / mul[y], x3 = x1 - x2 * mul[y]; write (x2); pc ('.'); for (size_t i = 1; x3 * mul[i] < mul[y]; ++i) pc ('0'); write (x3); }
template <class T, class... U> inline void read (T &x, U &...t) { read (x), read (t...); }
template <class T, class... U> inline void write (T x, U ...t) { write (x), write (t...); }
inline void flush () { fwrite (obuf, p3 - obuf, 1, stdout); }
};
using namespace IO;
int main ()
{
read (n);
for (int i = 1; i <= n; ++i) read (a[i]);
for (int i = 1; i <= n; ++i)
{
for (int j = i; j <= n; ++j)
if (!a[cur = j]) break;
if (!a[cur])
for (int j = i; j <= cur; ++j) b[j] = j <= lst + cur >> 1 ? j - lst : cur - j;
else
{
for (int j = i; j <= n; ++j) b[j] = j - lst;
break;
}
lst = cur, i = lst;
}
for (int i = 1; i <= n; ++i) write (b[i], ' ');
flush ();
return 0;
}
Author: $Segment$_$Tree$
《CSP》
MD我忘了这是哪篇课文
——码字清