【学习笔记】NOIP爆零赛7

结论专场,结果被踩暴了

青鱼和序列

赛时的做法是,维护 ∑ a i × i \sum a_i\times i ai×i的取值,发现只和最后一次操作 2 2 2的位置有关,于是递推 O ( n ) O(n) O(n)解决。

赛后发现还有更神奇的结论 第二个结论是,第一次进行操作 2 2 2过后, a a a序列变成回文的了,所以这之后 1 , 2 1,2 1,2操作就是等价的了。

这两个结论单独来看都很容易发现。不过接下来这个结论可能不容易看出:只要进行了操作 2 2 2,那么最后的结果就是一定的。事实上这不难从前 2 2 2个结论中看出。

青鱼和怪兽

猜了一个结论,直接二分答案就可以解决。

青鱼和区间

首先最直白的翻译是,设 S i S_i Si表示覆盖 i i i位置的区间的集合,那么合法的条件等价于 S i S_i Si互不相同。

然后有一个结论:不存在 i 1 < i 2 < j 1 < j 2 i_1<i_2<j_1<j_2 i1<i2<j1<j2,使得 S i 1 = S j 1 ≠ S i 2 = S j 2 S_{i_1}=S_{j_1}\ne S_{i_2}=S_{j_2} Si1=Sj1=Si2=Sj2

那么我们把相同等价类的位置提出来,记作区间 [ l i : r i ] [l_i:r_i] [li:ri],那么这些区间要么包含要么不相交,这个结构就非常显而易见了:我们可以把原序列划分成若干个连续段,同时不存在两个不属于同一个连续段的 i , j i,j i,j使得 S i = S j S_i=S_j Si=Sj。这个性质也等价于什么呢,对于询问区间 [ i : j ] [i:j] [i:j],要么 i , j i,j i,j在同一段中,要么 [ i : j ] [i:j] [i:j]不能制造断点,也就是说 [ i : j ] [i:j] [i:j]恰好是若干完整的段拼起来的。

现在我们只差最后一步:如何对这些若干不相交的 [ l i : r i ] [l_i:r_i] [li:ri]计数?

考虑一个普通至极的思路:正难则反。也就是说,我们减去分出来的段数 < n <n <n的方案数。那么我们考虑,假设分成了 j j j段,根据前面的观察,我们要把这分出来的 j j j段区分出来,然后对于长度为 l l l的一段,我们需要注意端点是不能包括在区间中的,因此有 ( l − 2 ) ( l − 1 ) 2 \frac{(l-2)(l-1)}{2} 2(l2)(l1)个可选择的区间,方案数为 2 ( l − 2 ) ( l − 1 ) 2 2^{\frac{(l-2)(l-1)}{2}} 22(l2)(l1)

有了上述动机,我们设 d p i dp_i dpi表示长度为 i i i的答案,有转移式: d p i = 2 i ( i + 1 ) 2 − ∑ j < i d p j f i , j dp_i=2^{\frac{i(i+1)}{2}}-\sum_{j<i}dp_jf_{i,j} dpi=22i(i+1)j<idpjfi,j,其中 f i , j f_{i,j} fi,j表示把 i i i分成 j j j段的所有方案的系数和。

复杂度 O ( n 3 ) O(n^3) O(n3)

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N=305;
int n,mod;
ll pw[N*N],dp[N][N],res[N];
void add(ll &x,ll y){
	x=(x+y)%mod;
}
int main(){
	cin>>n>>mod;
	pw[0]=1;for(int i=1;i<=n*n;i++)pw[i]=pw[i-1]*2%mod;
	dp[0][0]=1;
	for(int i=0;i<n;i++){
		for(int j=0;j<=i;j++){
			if(dp[i][j]){
				for(int k=1;k<=n-i;k++){
					add(dp[i+k][j+1],dp[i][j]*pw[(k-1)*(k-2)/2]);
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		res[i]=pw[i*(i+1)/2];
		for(int j=1;j<i;j++){
			res[i]=(res[i]-res[j]*dp[i][j])%mod;
		}
	}cout<<(res[n]+mod)%mod;
}

青鱼和游戏

考场上爆蛋了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值