#笛卡爾樹,構造#洛谷 7726 天體探測儀(Astral Detector)
阿新 • • 發佈:2021-11-11
笛卡爾樹,構造
分析
考慮每個數字一定會影響一定的範圍,
那麼可以記錄每個數影響的最長區間和產生的個數,
那麼通過這個可以解方程求出對於這個最長區間這個數的所在位置,
可以發現它可以滿足一個樹形結構,直接用笛卡爾樹的方法遍歷出來即可
程式碼
#include <cstdio> #include <cctype> #include <stack> #define rr register using namespace std; const int N=811; stack<int>st[N]; int a[N][N],L[N],R[N],n,fi[N],se[N],ls[N],rs[N]; inline signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline void print(int x){ if (ls[x]) print(ls[x]); printf("%d ",x); if (rs[x]) print(rs[x]); } signed main(){ n=iut(); for (rr int i=1;i<=n;++i) for (rr int j=1;j<=n-i+1;++j) ++a[i][iut()]; for (rr int i=1;i<=n;++i) for (rr int j=1;j<=n-i+1;++j) if (a[i][j]) L[j]=i,R[j]+=a[i][j]; for (rr int i=1;i<=n;++i){ for (rr int j=0;j<L[i];++j) if ((j+1)*(L[i]-j)==R[i]) {fi[i]=j,se[i]=L[i]-j-1; break;} } for (rr int i=n;i;--i){ if (!st[fi[i]].empty()) ls[i]=st[fi[i]].top(),st[fi[i]].pop(); if (!st[se[i]].empty()) rs[i]=st[se[i]].top(),st[se[i]].pop(); st[L[i]].push(i); } print(1); return 0; }