2024.11.26 鲜花

传话游戏题解

七里香
窗外的麻雀
在电线杆上多嘴
你说这一句
很有夏天的感觉
手中的铅笔
在纸上来来回回
我用几行字形容你是我的谁
秋刀鱼 的滋味
猫跟你都想了解
初恋的香味就这样被我们寻回
那温暖 的阳光
像刚摘的鲜艳草莓
你说你舍不得吃掉这一种感觉
雨下整夜
我的爱溢出就像雨水
院子落叶
跟我的思念厚厚一叠
几句是非
也无法将我的热情冷却
你出现在我诗的每一页
雨下整夜
我的爱溢出就像雨水
窗台蝴蝶
像诗里纷飞的美丽章节
我接着写
把永远爱你写进诗的结尾
你是我唯一想要的了解
雨下整夜
我的爱溢出就像雨水
院子落叶
跟我的思念厚厚一叠
几句是非
也无法将我的热情冷却
你出现在我诗的每一页
那饱满 的稻穗
幸福了这个季节
而你的脸颊像田里熟透的番茄
你突然 对我说
七里香的名字很美
我此刻却只想亲吻你倔强的嘴
雨下整夜
我的爱溢出就像雨水
院子落叶
跟我的思念厚厚一叠
几句是非
也无法将我的热情冷却
你出现在我诗的每一页
整夜 我的爱溢出就像雨水
窗台蝴蝶
像诗里纷飞的美丽章节
我接着写
把永远爱你写进诗的结尾
你是我唯一想要的了解

不是都听了一辈子了,能不能换一首

属于是思维极高的题,下辈子也想不到。

没有歧义时将 \((S_1)_i\) 简记为 \(s_i\)

首先考虑什么时候会重复,显然是当删除两个不同位置后结果一样。

设第 \(i\) 个点被删除的上一个时刻是 \(t_i\),也就是说在 \(S_{t_i+1}\) 时将 \(s_i\) 删掉。

我们将贡献同统一钦定放到后面,也就是说 \(1,2,2,1\to 1,2,1\) 我们认为是删除后面的 \(2\),而认为删除前面的不合法。

考虑形式化描述不合法的情况:\(s_i=s_j\land i<j\land t_i<t_j\) 并且不存在一个 \(k\) 满足 \(i<k<j\land s_k\not=s_i\)

容易发现这是序列不重的必要条件,感觉上也是充分的,考虑证明其充分性。

对于每个 \(S_t\) 单独考虑,将 \(t_i>t\) 设为 \(1\)\(t_i<t\) 设为 \(0\),考虑 dp 生成子序列的过程,容易发现一个子序列和一个 \(01\) 串一一对应。

考虑统计,发现这个限制依然不太好做,发现对于一个 \(k\) 其是否满足 \(s_k\not=s_i\) 是不重要的,因为其就算不满足也一定可以换成 \(i,k\) 的一个判断。

它等价于一个最小的 \(j\) 满足 \(i<j\land t_i<t_j\),若 \(s_i=s_j\) 则不合法,这个可以在笛卡尔树上做区间 dp。

具体的,设 \(dp_{l,r,p,v}\) 表示 \([l,r]\) 这段区间,其中填的 \(t\) 的最大值是 \(t_p=v\),转移是显然的,用前缀和优化可以做到 \(nm^5\)

考虑优化,发现 \(p\) 是不必要的,因为我们始终会将 \(t_p\)\(t_{r+1}\) 作比较,不妨直接在枚举状态时比较,这样就不用在转移时比较并记录这一维了,于是用前缀和优化可以做到 \(nm^3\)

考虑干掉 \(n\),我们最后要求的是前缀和 \(sm_{1,m,n}\) 其实容易发现对于 \(n\) 只有 \(m\) 个点会变化,也就是说 \(n\) 并不在关键的地方,可能可以联想到 \(sm{1,m,x}\) 是一个关于 \(x\)\(m+1\) 次多项式。

证明也不难,考虑 \(sm{1,1}\) 显然是 \(1\) 次多项式,而转移本质是卷积,其会把次数相加。

所以用拉差差出来即可。

复杂度是 \(\mathcal{O}(m^4)\) 的,不卡常什么的都是扯淡,关键的地方在于在 dp 时用 __int128_t 存值减少上界的取模(但是不要将 dp 数组开 __int128_t)。

Code
#include<bits/stdc++.h>
using namespace std;
using llt=long long;
using llf=long double;
using ull=unsigned long long;
#ifdef LOCAL
	FILE *InFile=freopen("in_out/in.in","r",stdin),*OutFile=freopen("in_out/out.out","w",stdout);
#else
	FILE *InFile=freopen("message.in","r",stdin),*OutFile=freopen("message.out","w",stdout);
#endif

const int M=207,MOD=1e9+7;
int dp[M][M][M],fac[M],ivf[M],n,m; int cs[M];

class LGG{
private: int cy[M],lmu[M],rmu[M],len;
public:
	void In(){len=m+2; for(int i=1;i<=len;++i) cy[i]=dp[1][m][i];}
	int operator()(int x){
		int y=0; memset(lmu,0,sizeof(lmu)),memset(rmu,0,sizeof(rmu));
		lmu[0]=1; for(int i=1;i<=len;++i) lmu[i]=1ll*lmu[i-1]*(x-i)%MOD;
		rmu[len+1]=1; for(int i=len;i;--i) rmu[i]=1ll*rmu[i+1]*(x-i)%MOD;
		for(int i=1;i<=len;++i) y=(y+1ll*cy[i]*lmu[i-1]%MOD*rmu[i+1]%MOD*ivf[i-1]%MOD*ivf[len-i]%MOD*(len-i&1?-1:1)+MOD)%MOD;
		return y;
    }
}Lgg;

int main(){
	ios::sync_with_stdio(0),cin.tie(nullptr),cout.tie(nullptr);
	cin>>n>>m; for(int i=1;i<=m;++i) cin>>cs[i];
	fac[0]=1; for(int i=1;i<=M-3;++i) fac[i]=1ll*fac[i-1]*i%MOD; cerr<<fac[M-3]<<endl;
	ivf[M-3]=657408467; for(int i=M-3;i;--i) ivf[i-1]=1ll*ivf[i]*i%MOD;
	for(int i=1;i<=m;++i) for(int j=0;j<=m+2;++j) dp[i][i-1][j]=dp[i+1][i][j]=1;
	for(int ln=1;ln<=m;++ln) for(int l=1;l+ln-1<=m;++l){
		int r=l+ln-1; dp[l][r][0]=0;
		for(int v=1;v<=m+2;++v){
			__int128_t t=0;
			for(int k=l;k<=r;++k) if(cs[k]!=cs[r+1]) t+=1ll*dp[l][k-1][v-1]*dp[k+1][r][v];
			dp[l][r][v]=(t+dp[l][r][v-1])%MOD;
		}
	}
	Lgg.In(); cout<<Lgg(n)<<endl;
}
P

posted @ 2024-11-26 21:23  xrlong  阅读(43)  评论(2编辑  收藏  举报