社论:『省选联考 2024』 迷宫守卫
0
签了五个小时到,望周知。
1
先猜了几个结论,全部假了。
然后发现如果没有花费的限制,答案就是排列本身。于是发现自己没办法搞清楚这个结构。
猜测答案形如,每次给能到达的最大的数铺路。写了第一个假做法。
尝试最大化第一个数,发现此后每次都相当于在一个空子树内最大化第一个数,特别有道理。
发现可以二分,记 \(f_u=f_{ls}+\min\{f_{rs},c_u\}\) dp 即可。写了第二个假做法。
发现最大化第一个数的时候可能在另一棵子树内,还要记录是否之前被钦定被唤醒。写了第三个假做法。
发现竟然有后效性,那咋办。发现如果这个数足够大,可以反悔根链上的若干个点。写了第四个假做法。
发现有了反悔之后就不能二分了,那咋办。先改成平方,直接从大往小枚举,这样总枚举量是 \(2^nn\) 的,每次还需要 dfs 整棵子树。对拍发现反悔得不够,如果新唤醒了一个点,右子树里的代价可以全部清空。发现这本质上是,对于当前最小化的子树,我们已经确定能够走到它了,所以可以直接清空子树内的所有之前唤醒的点,最后的答案一定是合法的。拿到 75pts。
然后发现从大往小枚举第一个数中,只有当前数的根链的 dp 值有变化,不需要每次都 dfs 一遍,这样复杂度就是 \(O(2^nn^2)\) 了。拿到 100pts。
然后发现所谓的“反悔根链上的若干个点”,实际上只有子树根这一个,好像又能二分了,但是常数可能更大。
2
代码
#include<bits/stdc++.h>
constexpr int rSiz=1<<21;
char rBuf[rSiz],*p1=rBuf,*p2=rBuf;
#define gc() (p1==p2&&(p2=(p1=rBuf)+fread(rBuf,1,rSiz,stdin),p1==p2)?EOF:*p1++)
template<class T>void rd(T&x){
char ch=gc();
for(;ch<'0'||ch>'9';ch=gc());
for(x=0;ch>='0'&&ch<='9';ch=gc())
x=(x<<1)+(x<<3)+(ch^48);
}
constexpr int _=131077;
constexpr long long inf=1e18;
long long Min(long long x,long long y){return x<y?x:y;}
int n,N,a[_],b[_];
long long m,c[_];
int f[_],siz[_],d[_];
long long t[_];
std::vector<int>e;
void dfs1(int u){
t[u]=inf;
if(u>=N)return e.push_back(a[u-N]),void();
if(d[u])d[u]=0,m+=c[u];
dfs1(u<<1);dfs1(u<<1|1);
}
void dfs2(int u){
if(u>=N||t[u]>=inf)return;
dfs2(u<<1);
if(t[u]==t[u<<1]+c[u])d[u]=1;
if(!d[u])dfs2(u<<1|1);
}
void solve(){
rd(n),rd(m);N=(1<<n);
for(int i=1;i<N+N;++i)siz[i]=d[i]=f[i]=0;
for(int i=1;i<N;++i)rd(c[i]);
for(int i=0;i<N;++i)rd(a[i]),b[a[i]]=i+N;
int u=1;for(int i=0;i<N;++i){
e.clear();dfs1(u);std::sort(e.begin(),e.end());
int p=0;bool ok=(u&1)&&d[u>>1];
if(ok)m+=c[u>>1],d[u>>1]=0;
for(;;){
p=e.back();e.pop_back();
if(ok&&p<=f[u^1])m-=c[u>>1],d[u>>1]=0,ok=0;
t[b[p]]=0;for(int y=b[p]>>1;y>=u;y>>=1)
t[y]=t[y<<1]+Min(t[y<<1|1],c[y]);
if(t[u]<=m)break;
}
m-=t[u];dfs2(u);printf("%d ",p);
if(i+1==N)return putchar(10),void();
for(int x=u=b[p];x;x>>=1)if((++siz[x])==1)f[x]=p;
for(int j=2;;j=j<<1,u>>=1)if(siz[u>>1]<j){u^=1;break;}
}
}
int main(){
int T;rd(T);
for(;T;--T)solve();
}

浙公网安备 33010602011771号