题解 P7888 「MCOI-06」Distinct Subsequences

此做法对字符集大小没有限制。也就是说,这道题可以加强,将字符串改为数列。

一个字符串的价值为该串的本质不同非空子序列个数。如果直接给定一个字符串,怎么求它的价值?我们考虑这样一个算法:

定义 det[x] 表示以字符 x 结尾的子序列个数。那么从 1 开始依次扫过去,对于扫到的每个字符 x,我们只要把 det[x] 替换为 sum+1 就行了,sum 表示当前所有 det 的和。

也就是 x 可以和任何一组拼接形成字符串,也可以自己单独形成。

考虑这个问题,要求所有子序列的价值和。如果转化为期望,就是对于扫到的每个 x,随机选择更新 det[x] 或者不更新,求最后的期望 sum

对于此处的期望,容易发现怎么做的概率都是相等的,因此可以直接相加取平均数。

得出期望之后乘上 2|S| 次方就行了。

代码很好写。目前最优解,23ms。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
char a[N];
const ll mod=1e9+7,inv2=500000004;
ll n,sum,tot=1,det[30];
inline void add(int x)
{
	ll tmp=det[x];
	det[x]=(sum+1+det[x])*inv2%mod;
	sum=(sum+sum-tmp+sum+1)*inv2%mod;
	sum=(sum+mod)%mod;
}
int main()
{
	scanf("%s",a+1);
	n=strlen(a+1);
	for (int i=1;i<=n;i++) add(a[i]-'a'),tot=(tot*2)%mod;
	cout << sum*tot%mod << endl;
	return 0;
}
posted @   Little09  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示