#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for (int i = (a); i <= (b); ++i)
#define REPD(i,a,b) for (int i = (a); i >= (b); --i)
#define FORI(i,n) REP(i,1,n)
#define FOR(i,n) REP(i,0,int(n)-1)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define vll vector<long long>
#define ll long long
#define SZ(x) int((x).size())
#define DBG(v) cerr << #v << " = " << (v) << endl;
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define fi first
#define se second
pair<vi,vll> solve_exp(vector<vi> g, int flip) {
int n = SZ(g);
vi best(n+1,n*n*3);
vll cnt(n+1,0);
if (flip) {
FOR(i,n) FOR(j,n) if (i!=j) g[i][j] = 1-g[i][j];
}
FOR(m,1<<n) {
int bad = 0, bit = 0;
FOR(j,n) if (m & (1<<j)) {
bit++;
FOR(i,j) if (m & (1<<i)) {
if (g[i][j]) bad++;
}
}
if (best[bit] > bad) {
best[bit] = bad;
cnt[bit] = 0;
}
if (best[bit] == bad) cnt[bit]++;
}
//cerr << "returning:\n";
//FOR(i,n+1) cerr << best[i] << " "; cerr << "\n";
//FOR(i,n+1) cerr << cnt[i] << " "; cerr << "\n";
return mp(best, cnt);
}
pair<vi,vll> solve(vector<vi> g, int flip) {
int n = SZ(g);
vi best(n+1,n*n*3);
vll cnt(n+1,0);
if (n <= 14) {
return solve_exp(g,flip);
}
best[0]=0; cnt[0]=1;
flip = 1-flip;
FOR(i,n) FOR(j,n) if (i!=j) g[i][j] = 1-g[i][j];
vi used(n);
FOR(vv,n) if (!used[vv]) {
queue<int> q;
vi comp;
q.push(vv);
comp.pb(vv);
used[vv] = 1;
while (!q.empty()) {
int u = q.front();
q.pop();
FOR(i,n) if (g[i][u] && !used[i]) {
//cerr << u+1 << " brings " << i+1 << "\n";
used[i] = 1;
q.push(i);
comp.pb(i);
}
}
int m = SZ(comp);
if (m == n) return solve_exp(g,flip);
vector<vi> gc(m, vi(m,0));
FOR(i,m) FOR(j,m) gc[i][j] = g[comp[i]][comp[j]];
pair<vi,vll> cur = solve(gc, flip);
vi tbest(n+1,n*n*3);
vll tcnt(n+1,0);
tbest[0]=0; tcnt[0]=1;
FOR(i,n+1) FOR(j,m+1) if (i+j <= n && i+j > 0) {
int val = best[i] + cur.fi[j] + i*j*flip;
//if (i+j == 1) cerr << i << " + " << j << " -> " << val << "\n";
if (val < tbest[i+j]) {
tbest[i+j] = val;
tcnt[i+j] = 0;
}
//if (i+j == 1) cerr << "cnt = " << tcnt[i+j] << "\n";
if (val == tbest[i+j]) tcnt[i+j] += cnt[i] * cur.se[j];
//if (i+j == 1) cerr << "cnt = " << tcnt[i+j] << "\n";
}
best = tbest;
cnt = tcnt;
}
//cerr << "returning:\n";
//FOR(i,n+1) cerr << best[i] << " "; cerr << "\n";
//FOR(i,n+1) cerr << cnt[i] << " "; cerr << "\n";
return mp(best, cnt);
}
const int N = 44;
int a[N];
int main() {
int n;
scanf("%d", &n);
FOR(i,n) scanf("%d", &a[i]);
//FOR(i,n) a[i] = i+1;
//random_shuffle(a,a+n);
vector<vi> g(n, vi(n,0));
FOR(j,n) FOR(i,j) if (a[i] > a[j]) g[i][j] = g[j][i] = 1;
pair<vi,vll> res = solve(g, false);
FORI(i,n) printf("%d %lld\n", res.fi[i], res.se[i]);
return 0;
}
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #include <bits/stdc++.h> using namespace std; #define REP(i,a,b) for (int i = (a); i <= (b); ++i) #define REPD(i,a,b) for (int i = (a); i >= (b); --i) #define FORI(i,n) REP(i,1,n) #define FOR(i,n) REP(i,0,int(n)-1) #define mp make_pair #define pb push_back #define pii pair<int,int> #define vi vector<int> #define vll vector<long long> #define ll long long #define SZ(x) int((x).size()) #define DBG(v) cerr << #v << " = " << (v) << endl; #define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) #define fi first #define se second pair<vi,vll> solve_exp(vector<vi> g, int flip) { int n = SZ(g); vi best(n+1,n*n*3); vll cnt(n+1,0); if (flip) { FOR(i,n) FOR(j,n) if (i!=j) g[i][j] = 1-g[i][j]; } FOR(m,1<<n) { int bad = 0, bit = 0; FOR(j,n) if (m & (1<<j)) { bit++; FOR(i,j) if (m & (1<<i)) { if (g[i][j]) bad++; } } if (best[bit] > bad) { best[bit] = bad; cnt[bit] = 0; } if (best[bit] == bad) cnt[bit]++; } //cerr << "returning:\n"; //FOR(i,n+1) cerr << best[i] << " "; cerr << "\n"; //FOR(i,n+1) cerr << cnt[i] << " "; cerr << "\n"; return mp(best, cnt); } pair<vi,vll> solve(vector<vi> g, int flip) { int n = SZ(g); vi best(n+1,n*n*3); vll cnt(n+1,0); if (n <= 14) { return solve_exp(g,flip); } best[0]=0; cnt[0]=1; flip = 1-flip; FOR(i,n) FOR(j,n) if (i!=j) g[i][j] = 1-g[i][j]; vi used(n); FOR(vv,n) if (!used[vv]) { queue<int> q; vi comp; q.push(vv); comp.pb(vv); used[vv] = 1; while (!q.empty()) { int u = q.front(); q.pop(); FOR(i,n) if (g[i][u] && !used[i]) { //cerr << u+1 << " brings " << i+1 << "\n"; used[i] = 1; q.push(i); comp.pb(i); } } int m = SZ(comp); if (m == n) return solve_exp(g,flip); vector<vi> gc(m, vi(m,0)); FOR(i,m) FOR(j,m) gc[i][j] = g[comp[i]][comp[j]]; pair<vi,vll> cur = solve(gc, flip); vi tbest(n+1,n*n*3); vll tcnt(n+1,0); tbest[0]=0; tcnt[0]=1; FOR(i,n+1) FOR(j,m+1) if (i+j <= n && i+j > 0) { int val = best[i] + cur.fi[j] + i*j*flip; //if (i+j == 1) cerr << i << " + " << j << " -> " << val << "\n"; if (val < tbest[i+j]) { tbest[i+j] = val; tcnt[i+j] = 0; } //if (i+j == 1) cerr << "cnt = " << tcnt[i+j] << "\n"; if (val == tbest[i+j]) tcnt[i+j] += cnt[i] * cur.se[j]; //if (i+j == 1) cerr << "cnt = " << tcnt[i+j] << "\n"; } best = tbest; cnt = tcnt; } //cerr << "returning:\n"; //FOR(i,n+1) cerr << best[i] << " "; cerr << "\n"; //FOR(i,n+1) cerr << cnt[i] << " "; cerr << "\n"; return mp(best, cnt); } const int N = 44; int a[N]; int main() { int n; scanf("%d", &n); FOR(i,n) scanf("%d", &a[i]); //FOR(i,n) a[i] = i+1; //random_shuffle(a,a+n); vector<vi> g(n, vi(n,0)); FOR(j,n) FOR(i,j) if (a[i] > a[j]) g[i][j] = g[j][i] = 1; pair<vi,vll> res = solve(g, false); FORI(i,n) printf("%d %lld\n", res.fi[i], res.se[i]); return 0; } |
English