3 | The 2nd Universal Cup. Stage Ω: Atlantis (Prime Contest)
The 2nd Universal Cup. Stage Ω: Atlantis (Prime Contest)
Prime Contest 也是 Prime。
3
Balanced Permutations
题意
给定一个大小为
给定整数
题解
这个题极其恶心。
可以看到平衡度就是笛卡尔树的子树大小和。
l=1 的做法
打个表,发现每次合法的最大值的位置在一个区间内,瞪出规律之后,把最大值尽量往前放,然后递归构造。往前放是为了让左半边的最大值变小,从而得到更小的字典序。
l>1 的做法
容易发现我们不会在
至于求重排方案,没法直接对笛卡尔树 dp,因为你无法辨别选择最大值的方案如何影响字典序大小。但是你可以从前到后枚举每个位置填多少,然后算出字典序比当前小的合法方案数。这样就可以 dp 了。
k 的做法
和上面差不多。
下面是一份来自 OnO 的
namespace OnO {
int hgh[100005];
inline void init(void) { for(int i=3; i<=100000; ++i) hgh[i]=hgh[(i-1)/2]+1; }
inline int* consMin(int*A,int n,int&val) {
if(n==0) return A;
if(n==1) {
*A=(++val);
return A+1;
}
int cnt=n-(1<<(hgh[n]+1))+1;
int siz=1<<hgh[n];
int L=0,R=0;
if(cnt) ++L,--cnt;
R=min(cnt,siz);
cnt-=R;
L+=cnt;
A=consMin(A,siz-1+L,val);
int*B=consMin(A+1,siz-1+R,val);
*A=(++val);
return B;
}
inline void consMin(int*A,int n) {
int v=0;
consMin(A,n,v);
}
inline int* consMax(int*A,int n,int&val) {
if(n==0) return A;
if(n==1) {
*A=(++val);
return A+1;
}
int cnt=n-(1<<(hgh[n]+1))+1;
int siz=1<<hgh[n];
int R=min(cnt,siz);
int L=cnt-R;
L+=siz-1; R+=siz-1;
int*B=consMax(A+L+1,R,val);
A=consMax(A,L,val);
*A=(++val);
return B;
}
inline void consMax(int*A,int n) {
int v=0;
consMax(A,n,v);
}
}