首页 > 其他分享 >AT_s8pc_2_e 部分文字列 题解

AT_s8pc_2_e 部分文字列 题解

时间:2024-04-07 09:22:59浏览次数:21  
标签:文字 frac 题解 ll height num 100010 sa s8pc

题目传送门

前置知识

后缀数组简介

解法

对于一个后缀 \(s_{sa_{i} \sim n}\),它产生了 \(n-sa_{i}+1\) 个前缀,其长度和为 \(\frac{(n-sa_{i}+1)(n-sa_{i}+2)}{2}\);和 \(s_{sa_{i-1} \sim n}\) 相比产生了 \(height_{i}\) 个相同的前缀,其长度和为 \(\frac{height_{i}(height_{i}+1)}{2}\)。

最终,有 $\sum\limits_{i=1}{n}\frac{(n-sa_{i}+1)(n-sa_{i}+2)}{2}-\sum\limits_{i=1}\frac{height_{i}(height_{i}+1)}{2} $ 即为所求,化简完得到 \(\frac{1}{2} \times (\frac{n(n+1)(2n+1)}{6}+\frac{n(n+1)}{2})-\sum\limits_{i=1}^{n}\frac{height_{i}(height_{i}+1)}{2}\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
ll sa[100010],rk[200010],oldrk[200010],id[100010],cnt[100010],key[100010],height[100010],a[100010],b[100010],fminn[100010][20];
char s[100010];
ll val(char x)
{
	return (ll)x;
}
void counting_sort(ll n,ll m)
{
	memset(cnt,0,sizeof(cnt));
	for(ll i=1;i<=n;i++)
	{
		cnt[key[i]]++;
	}
	for(ll i=1;i<=m;i++)
	{
		cnt[i]+=cnt[i-1];
	}
	for(ll i=n;i>=1;i--)
	{
		sa[cnt[key[i]]]=id[i];
		cnt[key[i]]--;
	}
}
void init_sa(char s[],ll len)
{
	ll m=127,tot=0,num=0,i,j,w;
	for(i=1;i<=len;i++)
	{
		rk[i]=val(s[i]);
		id[i]=i;
		key[i]=rk[id[i]];
	}
	counting_sort(len,m);
	for(w=1;tot!=len;w<<=1,m=tot)
	{
		num=0;
		for(i=len;i>=len-w+1;i--)
		{
			num++;
			id[num]=i;
		}
		for(i=1;i<=len;i++)
		{
			if(sa[i]>w)
			{
				num++;
				id[num]=sa[i]-w;
			}
		}
		for(i=1;i<=len;i++)
		{
			key[i]=rk[id[i]];
		}
		counting_sort(len,m);
		for(i=1;i<=len;i++)
		{
			oldrk[i]=rk[i];
		}
		tot=0;
		for(i=1;i<=len;i++)
		{
			tot+=(oldrk[sa[i]]!=oldrk[sa[i-1]]||oldrk[sa[i]+w]!=oldrk[sa[i-1]+w]);
			rk[sa[i]]=tot;
		}
	}
	for(i=1,j=0;i<=len;i++)
	{
		j-=(j>=1);
		while(s[i+j]==s[sa[rk[i]-1]+j])
		{
			j++;
		}
		height[rk[i]]=j;
	}
}
int main()
{
	ll n,sum=0,i;
	scanf("%s",s+1);
    n=strlen(s+1);
	init_sa(s,n);
	for(i=1;i<=n;i++)
	{
		sum+=height[i]*(height[i]+1)/2;
	}
	cout<<(n*(n+1)*(2*n+1)/6+n*(n+1)/2)/2-sum<<endl;
	return 0;
}

标签:文字,frac,题解,ll,height,num,100010,sa,s8pc
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18118369

相关文章

  • UVA1223 Editor 题解
    题目传送门前置知识后缀数组简介解法一个子串出现至少\(2\)次等价于有至少连续\(2\)个后缀以这个子串作为公共前缀。进行一次后缀排序后,有\(\max\limits_{i=1}^{|s|}\{height_{i}\}\)即为所求。代码#include<bits/stdc++.h>usingnamespacestd;#definelllong......
  • SP64 PERMUT1 - Permutations 题解
    题目传送门前置知识动态规划基础解法设\(f_{i,j}\)表示\(1\simi\)的全排列中存在\(j\)个逆序对的方案数,状态转移方程为\(f_{i,j}=\sum\limits_{k=j-\min(i-1,j)}^{j}f_{i-1,k}=\sum\limits_{k=0}^{j}f_{i-1,k}-\sum\limits_{k=0}^{j-\min(i-1,j)-1}f_{i-1,k}\)。需......
  • COCI2011-2012#3 ROBOT 题解
    洛谷题面部分分做法直接依照题意模拟即可。可以获得\(48\)分的好成绩。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;longlongn,m;structnode{ longlongx; longlongy;}point[100005];longlongrobotx=0,roboty=0;longlongquery(){......
  • 不知道什么题的题解
    多组测试数据,问你满足\(lcm\left(x,y\right)=n\)的数对\(\left(x,y\right)\)的数量。由于唯一分解定理,我们不妨令\(x=p_{1}^{a_1}\timesp_{2}^{a_2}\times\cdots\timesp_{i}^{a_i}\),同理,\(y=p_{1}^{b_1}\timesp_{2}^{b_2}\times\cdots\timesp_{i}^......
  • 第33次CSP认证500分题解
    近年来最简单的一次\(CSP\)认证,\(3\)个小时现场满分直接拿下。1、没啥好说的,直接开桶拿下。#include<bits/stdc++.h>usingnamespacestd;#defineN1000010template<classT>inlineTread(T&a){Tx=0,s=1;charc=getchar();while(!isdigi......
  • ABC348F 题解
    一些注意点:一看到这种题就应该往bitset的方向想。如果用bitset,就应该跳脱之前的思维,尝试从最朴素的暴力重新想起。看到这道题,发现直接做非常的不可做的样子,考虑bitset。我们可以先枚举左端点\(l\)。这样,当我们枚举\(j\)时,对于所有的\(k\)使得\(a_{k,j}=a_......
  • Windows 10のペイントで写真や画像に文字を入れる方法
    图片里插入文字参考元:https://faq.nec-lavie.jp/qasearch/1007/app/servlet/relatedqa?QID=019959写真や画像に文字が挿入されたこと......
  • Mathtype 公式在正文中高于文字的问题
    1.解决办法出现如图所示的问题:或者正文中也有类似的问题时,可以通过保存现有或者新建一个格式正确的Mathtype公式,并将其保存成文件:之后选择格式化公式:之后等待格式更改完毕即可!2.参考链接[1]如何处理MathType公式和正文不在同一行[2]如何解决在Word中格式刷之后公......
  • 网站使用CDN出现ttf woff等字体跨域问题解决方案
    如果cdn域名+资源路径是可以通过浏览器url地址栏打开的那么一般是因为nginx配置的原因,找到nginx的配置文件添加以下代码:# 允许指定域名访问;location ~ .*.(eot|ttf|ttc|otf|eot|woff|woff2|svg)(.*) { add_header Access-Control-Allow-Origin http(s)://......
  • arch安装教程+部分问题解决
    arch安装教程+部分问题解决网络配置#进入iwctliwctl#获取device名称我这里是wlan0,后面注意wlan0替换成你自己devicedevicelist#扫描附近wifistationwlan0scan#获取所有可连接wifi名字stationwlan0get-networksstationwlan0connect[wifi名]#输入密码......