ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【ABC214F】Substrings

2021-08-15 10:00:15  阅读:182  来源: 互联网

标签:pre ABC214F last int Substrings MAXN define mod


传送门

最近的 ABC 题目质量都好高啊,最后两题都吊打我。

不过 ABC214D 撞题 CF915F 喽。

题意:

给定长度为 \(n\) 的字符串,求本质不同的子序列数模 \(10^9+7\)。一个子序列必须满足不存在两个位置在原串中相邻。

Data range:\(n \le 2\,\times\,10^5\)

分析:

感谢 ABC 教会我一种新的 dp 科技。

第一眼可能是字符串算法,但是我们想想 kmp,trie,acam,sa,hash 似乎都解决不了这个问题()。

所以考虑 \(dp\),设 \(f(i)\) 为 \(s_1\sim s_i\) 里,以第 \(i\) 位结尾的,新产生的本质不同子序列个数。特殊地,令 \(f(0)=0\)。

我们发现,如果 \(s_i = s_{i-1}\),那么如果 \(i=2\),则 \(f(i)=0\);否则 \(f(i)=f(i-2)\)。

然后考虑 \(s_i \neq s_{i-1}\) 的情况,假如前面没有一个 \(s_k=s_i\),那么 \(f(i)=\sum_{j=0}^{i-2}f(j)\);否则,设 \(last\) 是前面第一个和 \(a_i\) 相等的位置 \(k\)(\(k<i-1)\),那么答案应该是 \(\sum_{j=last}^{i-2}f(j)\),特殊地,如果 \(k \neq 1\),那么还应该加上 \(f(k-1)\)。

那么上面的式子都可以用前缀和维护。我们发现上面的流程都要特判使得不加上 \(f(0)\) 这个东西,方便起见我们设 \(f(0)=0\),然后 \(pre\) 数组代表前缀和,\(pre_0=1\) 就行了。

最后我们思考一下为什么要对 \(f(0)\) 搞特殊。因为对于长度大于 \(0\) 的子序列,它下一个不能相邻。但如果本来是空串,它可以直接下一个选择 \(s_1\),没有不相邻的要求。

最后输出 \(\sum_{i=1}^nf(i)\) 就行了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define op(x) ((x&1)?x+1:x-1)
#define odd(x) (x&1)
#define even(x) (!odd(x))
#define lc(x) (x<<1)
#define rc(x) (lc(x)|1)
#define lowbit(x) (x&-x)
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
#define next Cry_For_theMoon
#define il inline
#define pb(x) push_back(x)
#define is(x) insert(x)
#define sit set<int>::iterator
#define mapit map<int,int>::iterator
#define pi pair<int,int>
#define ppi pair<int,pi>
#define pp pair<pi,pi>
#define fr first
#define se second
#define vit vector<int>::iterator
#define mp(x,y) make_pair(x,y)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double db;
using namespace std;
const int MAXN=2e5+10,mod=1e9+7;
char s[MAXN];
int n,f[MAXN],pre[MAXN],last[MAXN]; 
int main(){
	cin>>(s+1);
	n=strlen(s+1);
	pre[0]=1;
	rep(i,1,n){
		if(i==1){
			f[1]=1;
			pre[1]=2;
			continue;
		}
		if(s[i]==s[i-1]){
			f[i]=f[i-2];
		}else{
			f[i]=(pre[i-2]-pre[last[s[i]-'a'+1]-1]+mod)%mod;
			f[i]=(f[i]+f[last[s[i]-'a'+1]-1])%mod;
		}
		pre[i]=(pre[i-1]+f[i])%mod;
		last[s[i-1]-'a'+1]=i-1;
	} 
	printf("%d",(pre[n]-1+mod)%mod);
	return 0;
}

标签:pre,ABC214F,last,int,Substrings,MAXN,define,mod
来源: https://www.cnblogs.com/Cry-For-theMoon/p/15142729.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有