#include <bits/stdc++.h>
// #pragma GCC optimize ("O3")
// #pragma GCC target ("sse4")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i)
#define MAX(dst,src) dst = max(dst, (src))
#define MIN(dst,src) dst = min(dst, (src))
#define pb push_back
#define mp make_pair
#define st first
#define nd second
int A[50];
int b[1<<20];
LL bits(int L, int R) {
return (1LL<<R) - (1LL<<L);
}
bool has(LL mask, int bit) {
return mask&(1LL<<bit);
}
int bits_in(LL mask) {
return b[mask>>20] + b[mask&((1<<20)-1)];
}
int bits_in(LL mask, int L, int R) {
return bits_in(mask&bits(L,R));
}
LL set_in_range(LL mask, int L, int R, int value) {
return (mask&~bits(L,R))|bits(L,L+value);
}
int main(int argc, char* argv[]) {
FOR(i,1,1<<20) b[i] = b[i>>1] + (i&1);
int N;
scanf("%d", &N);
REP(i,N) {
scanf("%d", &A[i]);
--A[i];
}
vector<pair<LL,pair<int, LL>>> DP = {{0, {0, 1LL}}};
LL seen = 0;
REP(_,N) {
int bit = A[_];
int L = bit;
while (L > 0 && has(seen, L-1)) --L;
int R = bit + 1;
while (R < N && has(seen, R)) ++R;
vector<pair<LL,pair<int, LL>>> DPNext;
for (auto p: DP) {
LL mask = p.st;
auto result = p.nd;
int in_range = bits_in(mask,L,R);
DPNext.pb({
set_in_range(mask,L,R,in_range+1),
{ result.st + bits_in(mask,bit+1,N), result.nd }
});
DPNext.pb({
set_in_range(mask,L,R,in_range),
result
});
}
sort(DPNext.begin(), DPNext.end());
DP.clear();
for (auto p: DPNext) {
if (!DP.empty() && DP.back().st == p.st) {
if (DP.back().nd.st == p.nd.st) DP.back().nd.nd += p.nd.nd;
} else {
DP.push_back(p);
}
}
seen |= (1LL<<bit);
}
for (auto p: DP) if (p.st) printf("%d %lld\n", p.nd.st, p.nd.nd);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #include <bits/stdc++.h> // #pragma GCC optimize ("O3") // #pragma GCC target ("sse4") using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define MAX(dst,src) dst = max(dst, (src)) #define MIN(dst,src) dst = min(dst, (src)) #define pb push_back #define mp make_pair #define st first #define nd second int A[50]; int b[1<<20]; LL bits(int L, int R) { return (1LL<<R) - (1LL<<L); } bool has(LL mask, int bit) { return mask&(1LL<<bit); } int bits_in(LL mask) { return b[mask>>20] + b[mask&((1<<20)-1)]; } int bits_in(LL mask, int L, int R) { return bits_in(mask&bits(L,R)); } LL set_in_range(LL mask, int L, int R, int value) { return (mask&~bits(L,R))|bits(L,L+value); } int main(int argc, char* argv[]) { FOR(i,1,1<<20) b[i] = b[i>>1] + (i&1); int N; scanf("%d", &N); REP(i,N) { scanf("%d", &A[i]); --A[i]; } vector<pair<LL,pair<int, LL>>> DP = {{0, {0, 1LL}}}; LL seen = 0; REP(_,N) { int bit = A[_]; int L = bit; while (L > 0 && has(seen, L-1)) --L; int R = bit + 1; while (R < N && has(seen, R)) ++R; vector<pair<LL,pair<int, LL>>> DPNext; for (auto p: DP) { LL mask = p.st; auto result = p.nd; int in_range = bits_in(mask,L,R); DPNext.pb({ set_in_range(mask,L,R,in_range+1), { result.st + bits_in(mask,bit+1,N), result.nd } }); DPNext.pb({ set_in_range(mask,L,R,in_range), result }); } sort(DPNext.begin(), DPNext.end()); DP.clear(); for (auto p: DPNext) { if (!DP.empty() && DP.back().st == p.st) { if (DP.back().nd.st == p.nd.st) DP.back().nd.nd += p.nd.nd; } else { DP.push_back(p); } } seen |= (1LL<<bit); } for (auto p: DP) if (p.st) printf("%d %lld\n", p.nd.st, p.nd.nd); } |
English