类似于模拟,记录下标或者二分进行优化
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
struct node {
int u, v;
bool operator < (const node& rhy) const {
if(u != rhy.u) return u < rhy.u;
return v < rhy.v;
}
}ans[101010];
int n;
int b[101010], sum1[101010], sum2[101010], in1[101010], in2[101010];
bool vis[101010];
int main(){
while(scanf("%d", &n) == 1) {
sum1[0] = sum2[0] = 0;
memset(in1, 0x7f7f7f7f, sizeof(in1));
memset(in2, 0x7f7f7f7f, sizeof(in2));
for(int i = 1; i <= n; ++ i) {
int x;
scanf("%d", &x);
b[i] = x;
if(x == 1) {
sum1[i] = 1;
sum2[i] = 0;
sum1[i] += sum1[i-1];
sum2[i] += sum2[i-1];
in1[sum1[i]] = i;
}
else {
sum1[i] = 0;
sum2[i] = 1;
sum1[i] += sum1[i-1];
sum2[i] += sum2[i-1];
in2[sum2[i]] = i;
}
}
int dd = 0;
if(b[n] == 1) {
for(int i = 1; i <= sum1[n]; ++ i) {
if(i > sum2[n]) {
if(sum1[n]%i == 0) {
ans[dd].u = sum1[n]/i;
ans[dd].v = i;
dd ++;
}
continue;
}
int now = 0;
int cc1 = 0, cc2 = 0, w1 = 0, w2 = 0;
while(now < n) {
if(in1[w1+i] < in2[w2+i]) {
w1 = w1+i;
cc1 ++;
now = in1[w1];
w2 = sum2[now];
}
else if(in1[w1+i] > in2[w2+i]){
cc2 ++;
w2 = w2+i;
now = in2[w2];
w1 = sum1[now];
}
else break;
}
if(now == n && cc1 > cc2) {
ans[dd].u = cc1;
ans[dd].v = i;
dd ++;
}
}
}
else {
for(int i = 1; i <= sum2[n]; ++ i) {
if(i > sum1[n]) {
if(sum2[n]%i == 0) {
ans[dd].u = sum2[n]/i;
ans[dd].v = i;
dd ++;
}
continue;
}
int now = 0;
int cc1 = 0, cc2 = 0, w1 = 0, w2 = 0;
while(now < n) {
if(in1[w1+i] > in2[w2+i]) {
w2 = w2+i;
cc1 ++;
now = in2[w2];
w1 = sum1[now];
}
else if(in1[w1+i] < in2[w2+i]){
cc2 ++;
w1 = w1+i;
now = in1[w1];
w2 = sum2[now];
}
else break;
}
if(now == n && cc1 > cc2) {
ans[dd].u = cc1;
ans[dd].v = i;
dd ++;
}
}
}
sort(ans, ans+dd);
printf("%d\n", dd);
for(int i = 0; i < dd; ++ i)
printf("%d %d\n", ans[i].u, ans[i].v);
}
return 0;
}