CF2018F1~3 Solution

相当于计数如下正整数序列 a 的个数:

  • i[1,n],ai[1,n]
  • mini(i+ai1)maxi(iai+1)=k
  • i[1,n]maxajijminajij+1i

我们可以考虑枚举 min(i+ai1),这样通过 O(n) 的代价确定了每个 ai 的范围。

那么就只需要考虑第三个条件了,同时需要注意 a 需要顶到上界。

感觉可以按值大小依次填数唉。

如果按照原题目的想法,也可以看作答案区间 [l,r] 需要合法的扩展到并且可以扩展到全局。

哦,要计算所有的 k 啊。

那相当于是我可以考虑容斥,也就是我计算出 ansl,r 保证区间 [l,r] 内的点合法的话,也就是至少,那么恰好 ansl,r 也就是 ansl,r 减去所有包含他的区间的 ans,这一步显然可以 O(n2) 推出来。

那么我们考虑如何求出 ansl,r

考虑使用这样一种策略:除非右侧有一个点需要立刻向右走,否则就向左走,这样可以确保一个起点生成的方案唯一。

我们将一个方案描述为 (a,p) 表示数组 a 和访问顺序 p

根据 i+ai1r,iai+1laimax(r+1i,i+1l)

定义 dpl,r,0/1 为已经访问完了区间 [l,r] 当前有没有一个强制要求往右走的限制。

初始值显然是 dpi,i,0=dpi,i,1=[i[l,r]](n+1max(r+ii,i+1l))

考虑转移。

注意到如果你从 [l,r] 往外扩展一个位置,则它是第 rl+2 个访问的,则它的 a 值必须满足 max(rl+2,ri+1,il+1)

而且如果你填了 rl+2 也可以选择消去必须往右走的限制。

同时每一次扩展后导致长度增加,那么也有可能会导致又必须往右走。

所以可以设计出一个 O(n2) 每次的DP。

另外,对于一个合法的 a 其所有起始位置任意,所以需要除掉 rl+1

所以会有一个 O(n2) 枚举 l,r,再 O(n2) DP,求得 ansl,r 为钦定 [l,r] 内点为答案的 O(n4) 算法。

那么容斥下就是 ansl,r+ansl1,r+1ansl1,ransl,r+1 为真正答案。

另外 k=0 的答案用 nn 减掉其他即可。

int sol(int L,int R){
	for(int i=1;i<=n;++i)for(int j=i;j<=n;++j)f[i][j][0]=f[i][j][1]=0;
	for(int i=L;i<=R;++i)f[i][i][0]=f[i][i][1]=n+1-max(R-i+1,i-L+1);
	for(int len=2;len<=n;++len){
		for(int l=1,r=len;r<=n;++l,++r){
			int vl=(n+1-Max({R-l+1,l-L+1,len}));
			int vr=(n+1-Max({R-r+1,r-L+1,len}));
			f[l][r][0]=f[l+1][r][0]*vl%p;
			if(len>=max(R-r+1,r-L+1))(f[l][r][0]+=f[l][r-1][1])%=p;
			f[l][r][1]=(f[l+1][r][0]*vl%p+f[l][r-1][1]*vr%p)%p;
		}
	}
	// cout<<f[1][n][0]<<"\n";
	return f[1][n][0];
}

写出代码后可以发现,对于相同长度的区间,L,R 的变化是相同的,且贡献次数与DP过程中的 l,rL,R 的差量有关,而 len 在哪里都是常量,所以可以考虑将 L,R 的移动替代为 l,r 的移动。

也即,我们只处理 sol(nlen+1,n),但是l,r 的取值是 [1,2n],这样借助内部DP端点的移动替代了 L,R 的移动,则相同长度的DP只需要跑一次,就可以做到 O(n3) 了。

for(int len=1;len<=n;++len){
    sol(n-len+1,n);
    for(int l=1,r=len;r<=n;++r,++l)ans[l][r]=f[l][n+l-1][0]*inv[len]%p;
}

注意到 F3 需要一个 O(n2) 的DP。

我们注意到 一个方案中,第一次往右走的时刻就确定了左端点,当然反过来也是一样的。

所以如果我们可以考虑求一个固定左端点的DP。

也即如果我们可以求得 fl 表示所有合法区间左端点 l 的方案数之和,则 k 的答案就是 fnk+1fnk

我们对于每个 l 进行倒序DP,初始化 dp1,n,0=1,不记录 r,那么 [l,r] 的答案就是 dpr,r,1

可以运用上面那个技巧将 r 这个维度压掉,这样算 dpr,r,1 后需要乘上一个 r

这样就做到了 O(n2)

posted @   spdarkle  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示