正题

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


题目大意

长度为nnn的字符串,对于每个iii求字符串1∼i1\sim i1∼i部分有多少个不同的子串。


解题思路

对于整个串ans=∑i=1nn−i+1−heightians=\sum_{i=1}^nn-i+1-height_ians=∑i=1n​n−i+1−heighti​,考虑如何维护heightheightheight
往末尾加上一个字符会对heightheightheight造成很大影响,但是如果在字符串前面加上一个heightheightheight的话就不会对其他heightheightheight造成影响了。

所以先翻转字符串,问题变为每次在前面加上一个字符。

首先离线后缀排好序,然后每次加入一个字符时,我们用平衡树找已经插入的前驱和后继然后用STSTST表来求到他们的LCPLCPLCP(也就是更新后的heightheightheight)即可。


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int N=1e5+10;
int n,m,a[N],b[N],height[N],lg[N];
int c[N],sa[N],rk[N],x[N],y[N];
int f[20][N];long long ans;
set<int> s;
void Qsort(){for(int i=1;i<=m;i++)c[i]=0;for(int i=1;i<=n;i++)c[x[i]]++;for(int i=1;i<=m;i++)c[i]+=c[i-1];for(int i=n;i>=1;i--)sa[c[x[y[i]]]--]=y[i],y[i]=0;return;
}
void SA(){for(int i=1;i<=n;i++)x[i]=a[i],y[i]=i;Qsort();for(int w=1;w<=n;w<<=1){int p=0;for(int i=n-w+1;i<=n;i++)y[++p]=i;for(int i=1;i<=n;i++)if(sa[i]>w)y[++p]=sa[i]-w;Qsort();swap(x,y);p=x[sa[1]]=1;for(int i=2;i<=n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+w]==y[sa[i-1]+w])?p:++p;if(p==n)break;m=p;}return;
}
void Get_Height(){int k=0;for(int i=1;i<=n;i++)rk[sa[i]]=i;for(int i=1;i<=n;i++){if(rk[i]==1)continue;if(k)k--;int j=sa[rk[i]-1];while(i+k<=n&&j+k<=n&&a[i+k]==a[j+k])k++;height[rk[i]]=k;}return;
}
void RMQ(){lg[0]=-1;for(int i=1;i<=n;i++)lg[i]=lg[i/2]+1,f[0][i]=height[i];for(int i=1;i<19;i++)for(int j=1;j+(1<<i-1)<=n;j++)f[i][j]=min(f[i-1][j],f[i-1][j+(1<<i-1)]);return;
}
int LCP(int l,int r){l++;int z=lg[r-l+1];return min(f[z][l],f[z][r+1-(1<<z)]);
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);b[i]=a[i];}sort(b+1,b+1+n);m=unique(b+1,b+1+n)-b-1;for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+m,a[i])-b;for(int i=1;i<=n/2;i++)swap(a[i],a[n-i+1]);SA();Get_Height();RMQ();for(int i=n;i>=1;i--){s.insert(rk[i]);set<int>::iterator it=s.find(rk[i]);int k=0;if(it!=s.begin()){int p=*(--it);k=LCP(p,rk[i]);++it;}++it;if(it!=s.end()){int p=*it;k=max(k,LCP(rk[i],p));}ans+=n-i+1-k;printf("%lld\n",ans);}
}

P4070-[SDOI2016]生成魔咒【SA,平衡树】相关推荐

  1. P4070 [SDOI2016]生成魔咒

    P4070 [SDOI2016]生成魔咒 题意: 有n个字符xi,每次在S的末尾加入一个字符,(一开始S为空),每次加入xi后的不相同字串有多少个 题解: 做这个题首先要会后缀数组P3809 [模板] ...

  2. 洛谷 P4070 [SDOI2016]生成魔咒 解题报告

    P4070 [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 \(1\).\(2\) 拼凑起来形成一个魔咒串 \([1,2]\). 一个魔咒 ...

  3. bzoj4516 / P4070 [SDOI2016]生成魔咒

    P4070 [SDOI2016]生成魔咒 后缀自动机 每插入一个字符,对答案的贡献为$len[last]-len[fa[last]]$ 插入字符范围过大,所以使用$map$存储. (去掉第35行就是裸 ...

  4. P4070 [SDOI2016]生成魔咒(SAM len数组的含义)

    [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 , 2 1,2 1,2 拼凑起来形成一个魔咒串 [ 1 , 2 ] [1,2] [1, ...

  5. 洛谷 P4070 [SDOI2016]生成魔咒 后缀自动机

    题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1, ...

  6. P4070 [SDOI2016]生成魔咒(SAM)

    传送门 用后缀数组做的真的心累 后缀数组+ST表+反串思维+set(或平衡树)动态维护 h e i g h t height height数组 然后用 S A M SAM SAM就是模板题- 要求本质 ...

  7. luogu P4070 [SDOI2016]生成魔咒

    首先有两个结论: 1.后缀自动机具有最简性,即每种不同的子串只会在sam上体现一次,体现形式是sam上一条由root出发的路径. 2.一个字符串不同子串的个数等于所有关键节点的max(x)-min(x ...

  8. BZOJ4516: [Sdoi2016]生成魔咒

    BZOJ4516: [Sdoi2016]生成魔咒 Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示. 例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒 ...

  9. [SDOI2016]生成魔咒

    4516: [Sdoi2016]生成魔咒 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1460  Solved: 835 [Submit][Sta ...

  10. BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]

    4516: [Sdoi2016]生成魔咒 题意:询问一个字符串每个前缀有多少不同的子串 做了一下SDOI2016R1D2,题好水啊随便AK 强行开map上SAM 每个状态的贡献就是\(Max(s)-M ...

最新文章

  1. C语言深度剖析书籍学习记录 第一章 关键字
  2. LintCode刷题笔记-- BackpackIII
  3. 【Python】【数据库】
  4. 多语言界面 Web 站点的几个 Tip
  5. git解决 “fatal: Could not read from remote repository.“
  6. Android小应用-----画画板
  7. 贺利坚老师汇编课程29笔记:在代码段使用栈将程序定义的数据逆序
  8. matlab 二维低通滤波器,matlab二维低通滤波器
  9. 压力单位MPa、Psi和bar之间换算公式
  10. kali linux2.0输入法,kali2.0 设置输入法 找了好久,亲测有效
  11. 【记录】mmsegmentation 训练自己的数据集
  12. Maxima 的绘图功能 1
  13. 36岁大数据人被中台问倒,没点架构思维,连面试都过不了?
  14. 多功能运算求解器_matlab中bsxfun函数
  15. java冒泡排序经典代码(Java冒泡排序)
  16. asp毕业设计—— 基于asp+access的实验室设备管理系统设计与实现(毕业论文+程序源码)——实验室设备管理系统
  17. 中科燕园GIS外包--移动GIS
  18. 原SAP全球副总裁邓永富加盟金蝶,担任金蝶集团副总裁
  19. serial.serialutil.SerialException: could not open port 'COM1': PermissionError(13, '拒绝访问。', None, 5)
  20. 评论一下《PPT演义》

热门文章

  1. oracle绑定变量过多,oracle - 在SQL Plus中使用绑定变量并返回多行? - 堆栈内存溢出...
  2. java如何解压rar文件怎么打开,java解压rar文件
  3. linux调用v4l2获取视频,嵌入式Linux:V4L2视频采集操作流程和接口说明
  4. io流图解 java_详细讲解JAVA中的IO流
  5. linux sudo 必须属于用户ID0,sudo:/usr/bin/sudo 务必属于用户 ID 0(的用户)并且设置 setuid 位...
  6. 前台提交数据到php mysql,建立一个基础的MySQL数据库,使用PHP来抓取和处理数据,并抛出给前台...
  7. 数据结构——二叉树的最长路径问题
  8. leetcote34. 在排序数组中查找元素的第一个和最后一个位置
  9. [JS-BOM]BOM_Location地址栏对象
  10. [C++11]独占的智能指针unique_ptr的初始化和使用