#笛卡尔树,构造#洛谷 7726 天体探测仪(Astral Detector)

题目传送门


分析

考虑每个数字一定会影响一定的范围,

那么可以记录每个数影响的最长区间和产生的个数,

那么通过这个可以解方程求出对于这个最长区间这个数的所在位置,

可以发现它可以满足一个树形结构,直接用笛卡尔树的方法遍历出来即可


代码

#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; 
}
posted @ 2021-11-11 20:09  lemondinosaur  阅读(121)  评论(0)    收藏  举报