题意:有$n$个数轴上的绿洲,给定它们的坐标,有一只骆驼想要访问所有绿洲,当它的驼峰容量为$V$时,它可以走到和当前绿洲距离$\leq V$的绿洲,并可以继续走,它也可以用一次跳跃到达任意一个绿洲,只不过这样会让驼峰容量变为$\left\lfloor\frac V2\right\rfloor$,问它可以从哪些位置开始使得最终可以到达所有绿洲
当$V$为定值时,它不跳跃就能到达的地方是许多个区间,每个区间内相邻两点距离$\leq V$,先对所有的$O(\log V)$个$V$预处理出这些区间,我们把$V'=\left\lfloor\frac V{2^i}\right\rfloor$时的这些区间称为第$i$层的区间
问题变为:硬点$0$层选一个区间,在$0$层以外每层选一个区间,使得这些区间的并是$[1,n]$,问是否可行
考虑状压,设$fl_i=x$表示在$i$状态的层中选了区间,最远能覆盖到$[1,x]$,转移就枚举不在$i$中的层$j$,加入$j$层中包含$fl_i$的右端点最大的区间即可,类似地定义$fr_i$,转移也是类似的,注意这里的状压不包括$0$层
最后对$0$层的每一个区间$[l,r]$,如果存在$x$使得$fl_x\geq l-1,fr_{all-x}\leq r+1$那么整个区间都可以,直接枚举所有$x$给区间打标记即可
状压DP那一步好厉害啊...
#includevoid fmax(int&a,int b){ if(b>a)a=b;}void fmin(int&a,int b){ if(b d?i:l[i-1]; r[n]=n; for(i=n-1;i>0;i--)r[i]=x[i+1]-x[i]>d?i:r[i+1]; l[0]=1; r[n+1]=n;}int fl[262144],fr[262144],s[200010];void gao(int l,int r){ if(l<=r){ s[l]++; s[r+1]--; }}int main(){ int V,M,i,j; scanf("%d%d",&n,&V); for(i=1;i<=n;i++)scanf("%d",x+i); for(M=0;V;V>>=1)pre(M++,V); pre(M,0); fr[0]=n+1; for(i=1;i<1< >j&1){ fmax(fl[i],r[j+1][fl[i^(1<