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
| #include <stdio.h> #include <iostream> #include <algorithm> #include <memory.h> #include <vector>
using namespace std; typedef long long LL;
const int maxn = 64005; #define pb push_back
int a[maxn],a0[maxn],n,tot,f[maxn],g[maxn]; vector<int> vec[maxn]; int mx1[maxn],mx2[maxn],bac[maxn],del[maxn];
void Print() { printf("%d\n",tot); for (int i=1;i<=tot;i++) { int len=vec[i].size(); printf("%d ",len); for (int j=len-1;j>=0;j--) printf("%d%c",vec[i][j]," \n"[j==0]); } } void insert1(int x,int v) { for (int i=x;i<=n;i+=i&-i) mx1[i]=max(mx1[i],v); } void insert2(int x,int v) { for (int i=x;i;i-=i&-i) mx2[i]=max(mx2[i],v); } int query1(int x) { int res=0; for (int i=x;i;i-=i&-i) res=max(res,mx1[i]); return res; } int query2(int x) { int res=0; for (int i=x;i<=n;i+=i&-i) res=max(res,mx2[i]); return res; }
void DP() { ++tot; memset(mx1,0,n+1<<2); memset(mx2,0,n+1<<2); int ans1=0,ans2=0;; for (int i=1;i<=n;i++) { f[i]=query1(a[i])+1; g[i]=query2(a[i])+1; insert1(a[i],f[i]); insert2(a[i],g[i]); ans1=max(ans1,f[i]); ans2=max(ans2,g[i]); } memset(del,0,n+1<<2); if (ans1>ans2) { for (int t=ans1,i=n;t;i--) if (f[i]==t) del[a[i]]=1,t--,vec[tot].pb(a0[i]); } else { for (int t=ans2,i=n;t;i--) if (g[i]==t) del[a[i]]=1,t--,vec[tot].pb(a0[i]); } for (int i=1;i<=n;i++) bac[i]=bac[i-1]+1-del[i]; int pos=0; for (int i=1;i<=n;i++) if (!del[a[i]]) a0[++pos]=a0[i],a[pos]=bac[a[i]]; n=pos; } int main() { #ifndef ONLINE_JUDGE freopen("delete.in","r",stdin); freopen("delete.out","w",stdout); #endif scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]),a0[i]=a[i]; while (n) DP(); Print(); return 0; }
|