正题

题目链接:https://www.luogu.com.cn/problem/P4248


题目大意

TiT_iTi​表示后缀i∼ni\sim ni∼n
一个字符串求
∑i=1n∑j=inlen(Ti)+len(Tj)−2∗lcp(Ti,Tj)\sum_{i=1}^n\sum_{j=i}^nlen(T_i)+len(T_j)-2*lcp(T_i,T_j)i=1∑n​j=i∑n​len(Ti​)+len(Tj​)−2∗lcp(Ti​,Tj​)


解题思路

有两种做法,这里标程用的是SAMSAMSAM

SAMSAMSAM做法

这个式子和树上路径长度很像,顺着这个思路,我们可以想到SAMSAMSAM上的ParentParentParent树。

两个后缀的lcplcplcp就是ParentParentParent树上的LCALCALCA的节点代表的字符串,我们让边长为lenx−lenfailxlen_x-len_{fail_x}lenx​−lenfailx​​,然后答案就变为了树上的每条路径长度和。

那一条边的贡献就是(num−sizx)∗sizx∗len(num-siz_x)*siz_x*len(num−sizx​)∗sizx​∗len‘
统计即可,时间复杂度O(n)O(n)O(n)

SASASA做法

我们先计算定值∑i=1n∑j=inlen(Ti)+len(Tj)\sum_{i=1}^n\sum_{j=i}^nlen(T_i)+len(T_j)∑i=1n​∑j=in​len(Ti​)+len(Tj​)
这里的定值就是n∗(n−1)∗(n+1)2\frac{n*(n-1)*(n+1)}{2}2n∗(n−1)∗(n+1)​

然后我们考虑如何计算LCPLCPLCP的和
heighti=LCP(i,i−1)height_i=LCP(i,i-1)heighti​=LCP(i,i−1)
我们有LCP(i,j)=min{heightk}(i<k≤j)LCP(i,j)=min\{height_k\}(i<k\leq j)LCP(i,j)=min{heightk​}(i<k≤j)
所以这里的答案就变为了∑i=2n∑j=inmin{heightk}(i≤k≤j)\sum_{i=2}^{n}\sum_{j=i}^nmin\{height_k\}(i\leq k\leq j)i=2∑n​j=i∑n​min{heightk​}(i≤k≤j)
我们每个heightiheight_iheighti​的贡献分开统计即可


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2e6+10;
struct node{ll to,next,w;
}a[N];
ll n,tot,ls[N],ans,num,siz[N];
ll next[N][26],len[N],fail[N],cnt;
char s[N];
void New_Point(ll x,ll v){next[x][v]=++cnt;len[cnt]=len[x]+1;
}
void addl(ll x,ll y,ll w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;
}
void Make_SAM(){ll now;now=cnt=1;for(ll i=1;i<=n;i++){ll val=s[i]-'a';New_Point(now,val);ll x=now,y;now=cnt;for(y=fail[x];y;y=fail[y])if(!next[y][val])next[y][val]=now;else{if(len[y]+1==len[next[y][val]])fail[now]=next[y][val];else{ll z=next[y][val];New_Point(y,val);fail[cnt]=fail[z];fail[z]=fail[now]=cnt;for(ll i=0;i<26;i++)next[cnt][i]=next[z][i];for(ll j=y;j;j=fail[j])if(next[j][val]==z)next[j][val]=cnt;}break;}siz[now]=1;if(!y) fail[now]=1;}for(ll i=2;i<=cnt;i++){num+=siz[i];addl(fail[i],i,len[i]-len[fail[i]]);}
}
void dfs(ll x){for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;dfs(y);ans+=siz[y]*(num-siz[y])*a[i].w;siz[x]+=siz[y];}
}
int main()
{scanf("%s",s+1);n=strlen(s+1);Make_SAM();dfs(1);printf("%lld",ans);
}

P4248-[AHOI2013]差异【SAM or SA】相关推荐

  1. P4248 [AHOI2013]差异

    P4248 [AHOI2013]差异 题意: ∑1≤i<j≤nlen(Ti)+len(Tj)−2∗lcp(Ti,Tj)\sum_{1\leq i<j\leq n}len(T_{i})+le ...

  2. BZOJ3238: [Ahoi2013]差异

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 4840  Solved: 2298 [Submit][Stat ...

  3. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2326  Solved: 1054 [Submit][Stat ...

  4. bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 3443  Solved: 1562 [Submit][Stat ...

  5. 【bzoj3238】[Ahoi2013]差异

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 3425  Solved: 1559 [Submit][Stat ...

  6. 3238: [Ahoi2013]差异

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2106  Solved: 953 [Submit][Statu ...

  7. [BZOJ3238] [AHOI2013] 差异 - 后缀自动机

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1968  Solved: 896 [Submit][Statu ...

  8. BZOJ3238[Ahoi2013]差异

    BZOJ3238[Ahoi2013]差异 题目描述 n<=500000n<=500000n,都是小写字母 输入 一行,一个字符串S 输出 一行,一个整数,表示所求值 Solution 公式 ...

  9. BZOJ_3238_[Ahoi2013]差异_后缀自动机

    BZOJ_3238_[Ahoi2013]差异_后缀自动机 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sam ...

最新文章

  1. go语言linux环境配置nginx,搭建wss
  2. 【话题揭秘】某大型国有银行的敏捷落地实践
  3. LintCode 125. 背包问题 II(DP)
  4. Android2D绘图二
  5. 【带着canvas去流浪(6)】绘制雷达图
  6. 华为亮相英国首次 5G 直播;百度 AI 接入医院信息系统;小米成立质量办公室 | 极客头条...
  7. 原型模式-prototype
  8. mac怎么装java eclipse_如何在Mac系统安装eclipse并运行java程序
  9. 面试字节跳动社招,我工资涨了60%,附带面经
  10. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_17-异常处理-可预知异常处理-异常处理测试...
  11. C 语言调用python 脚本函数
  12. 洛谷oj---1036 选数
  13. 高等数学(第七版)同济大学 习题2-1 个人解答
  14. Android Java开发实例项目+游戏视频教程免费下载咯。。
  15. Kali Linux渗透测试——WEB渗透(二)
  16. HTML网引入插件时出现网页下面部分内容不显示解决方案
  17. 记dubbo consumer服务因订阅其他有异常的服务导致超时的问题
  18. logistic混沌 matlab,混沌映射(序列)matlab算法“小全”:Logistic、Henon、帐篷、kent(含混沌二值图像生成函数)...
  19. ARM LINUX 扩展串口
  20. Quantopian教程系列三

热门文章

  1. 化妆definer是什么意思_化妆品上的r是什么意思
  2. 班尼机器人维修方法_梅州市ABB机器人控制器维修中心
  3. c语言中二重指针如何赋值,关于二重指针释放的有关问题
  4. 做流向图_各类型供热暖系统图大全,一饱眼福!
  5. android刷新时的圆形动画_Android自定义加载圈动画效果
  6. realloc函_[转载]realloc函数的使用及注意事项(转)
  7. android 手机交互设计,移动设备交互设计比较
  8. C++ vector容器中常见的三种遍历方式
  9. [PAT乙级]1047 编程团体赛
  10. [Java基础]System类的常用方法