树状数组+二分
TLE 80分
话说 n⋅(log2n)2应该不会T吧?
//#include <Windows.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
// #define DEBUG 1 // 调试开关
struct IO {
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
char buf[MAXSIZE], *p1, *p2;
char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
IO() : p1(buf), p2(buf), pp(pbuf) {}
~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
char gc() {
#if DEBUG // 调试,可显示字符
return getchar();
#endif
if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
return p1 == p2 ? ' ' : *p1++;
}
bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
template <class T>
void read(T &x) {
double tmp = 1;
bool sign = 0;
x = 0;
char ch = gc();
for (; !isdigit(ch); ch = gc())
if (ch == '-') sign = 1;
for (; isdigit(ch); ch = gc()) x = x * 10 + (ch - '0');
if (ch == '.')
for (ch = gc(); isdigit(ch); ch = gc())
tmp /= 10.0, x += tmp * (ch - '0');
if (sign) x = -x;
}
void read(char *s) {
char ch = gc();
for (; blank(ch); ch = gc());
for (; !blank(ch); ch = gc()) *s++ = ch;
*s = 0;
}
void read(char &c) { for (c = gc(); blank(c); c = gc()); }
void push(const char &c) {
#if DEBUG // 调试,可显示字符
putchar(c);
#else
if (pp - pbuf == MAXSIZE) fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
*pp++ = c;
#endif
}
template <class T>
void write(T x) {
if (x < 0) x = -x, push('-'); // 负数输出
static T sta[35];
T top = 0;
do {
sta[top++] = x % 10, x /= 10;
} while (x);
while (top) push(sta[--top] + '0');
}
template <class T>
void write(T x, char lastChar) {
write(x), push(lastChar);
}
} io;
int arr[N];
int treesum0[N];
int treesum1[N];
int lowbit(const int& x)
{
return x & (-x);
}
void modify(int* treesum,const int& id,const int& value)
{
for(int i = id;i <= N - 3;i += lowbit(i))
treesum[i] += value;
return;
}
int getsum(int* treesum,const int& id)
{
int ans = 0;
for(int i = id;i >= 1;i -= lowbit(i))
ans += treesum[i];
return ans;
}
int n;
int main(void)
{
// freopen("test.in","r",stdin);
// freopen("play.out","w",stdout);
io.read(n);
for(int i = 1;i <= n;i++)
io.read(arr[i]);
for(int i = 1;i <= n;i++)
if(arr[i])
modify(treesum1,i,1);
else
modify(treesum0,i,1);
while(getsum(treesum0,n) || getsum(treesum1,n))
{
int st0 = n + 1,st1 = n + 1;
int L = 1,R = n;
while(L < R)
{
int M = L + R >> 1;
if(getsum(treesum0,M))
R = M;
else
L = M + 1;
}
st0 = L;
L = 1,R = n;
while(L < R)
{
int M = L + R >> 1;
if(getsum(treesum1,M))
R = M;
else
L = M + 1;
}
st1 = L;
int st;
bool flag;
if(st0 < st1)
{
st = st0;
flag = 0;
}
else
{
st = st1;
flag = 1;
}
while(1)
{
io.write(st,' ');
if(flag)
modify(treesum1,st,-1);
else
modify(treesum0,st,-1);
int L = st + 1,R = n + 1;
int fg = 0;
if(flag)
fg = getsum(treesum0,st);
else
fg = getsum(treesum1,st);
while(L < R)
{
int M = L + R >> 1;
if(flag)
{
if(getsum(treesum0,M) - fg)
R = M;
else
L = M + 1;
}
else
{
if(getsum(treesum1,M) - fg)
R = M;
else
L = M + 1;
}
}
st = L;
if(st == n + 1)
break;
flag = !flag;
}
io.push('\n');
}
return 0;
}