P4070-[SDOI2016]生成魔咒【SA,平衡树】
正题
题目链接: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=1nn−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,平衡树】相关推荐
- P4070 [SDOI2016]生成魔咒
P4070 [SDOI2016]生成魔咒 题意: 有n个字符xi,每次在S的末尾加入一个字符,(一开始S为空),每次加入xi后的不相同字串有多少个 题解: 做这个题首先要会后缀数组P3809 [模板] ...
- 洛谷 P4070 [SDOI2016]生成魔咒 解题报告
P4070 [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 \(1\).\(2\) 拼凑起来形成一个魔咒串 \([1,2]\). 一个魔咒 ...
- bzoj4516 / P4070 [SDOI2016]生成魔咒
P4070 [SDOI2016]生成魔咒 后缀自动机 每插入一个字符,对答案的贡献为$len[last]-len[fa[last]]$ 插入字符范围过大,所以使用$map$存储. (去掉第35行就是裸 ...
- P4070 [SDOI2016]生成魔咒(SAM len数组的含义)
[SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 , 2 1,2 1,2 拼凑起来形成一个魔咒串 [ 1 , 2 ] [1,2] [1, ...
- 洛谷 P4070 [SDOI2016]生成魔咒 后缀自动机
题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1, ...
- P4070 [SDOI2016]生成魔咒(SAM)
传送门 用后缀数组做的真的心累 后缀数组+ST表+反串思维+set(或平衡树)动态维护 h e i g h t height height数组 然后用 S A M SAM SAM就是模板题- 要求本质 ...
- luogu P4070 [SDOI2016]生成魔咒
首先有两个结论: 1.后缀自动机具有最简性,即每种不同的子串只会在sam上体现一次,体现形式是sam上一条由root出发的路径. 2.一个字符串不同子串的个数等于所有关键节点的max(x)-min(x ...
- BZOJ4516: [Sdoi2016]生成魔咒
BZOJ4516: [Sdoi2016]生成魔咒 Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示. 例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒 ...
- [SDOI2016]生成魔咒
4516: [Sdoi2016]生成魔咒 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1460 Solved: 835 [Submit][Sta ...
- BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]
4516: [Sdoi2016]生成魔咒 题意:询问一个字符串每个前缀有多少不同的子串 做了一下SDOI2016R1D2,题好水啊随便AK 强行开map上SAM 每个状态的贡献就是\(Max(s)-M ...
最新文章
- C语言深度剖析书籍学习记录 第一章 关键字
- LintCode刷题笔记-- BackpackIII
- 【Python】【数据库】
- 多语言界面 Web 站点的几个 Tip
- git解决 “fatal: Could not read from remote repository.“
- Android小应用-----画画板
- 贺利坚老师汇编课程29笔记:在代码段使用栈将程序定义的数据逆序
- matlab 二维低通滤波器,matlab二维低通滤波器
- 压力单位MPa、Psi和bar之间换算公式
- kali linux2.0输入法,kali2.0 设置输入法 找了好久,亲测有效
- 【记录】mmsegmentation 训练自己的数据集
- Maxima 的绘图功能 1
- 36岁大数据人被中台问倒,没点架构思维,连面试都过不了?
- 多功能运算求解器_matlab中bsxfun函数
- java冒泡排序经典代码(Java冒泡排序)
- asp毕业设计—— 基于asp+access的实验室设备管理系统设计与实现(毕业论文+程序源码)——实验室设备管理系统
- 中科燕园GIS外包--移动GIS
- 原SAP全球副总裁邓永富加盟金蝶,担任金蝶集团副总裁
- serial.serialutil.SerialException: could not open port 'COM1': PermissionError(13, '拒绝访问。', None, 5)
- 评论一下《PPT演义》
热门文章
- oracle绑定变量过多,oracle - 在SQL Plus中使用绑定变量并返回多行? - 堆栈内存溢出...
- java如何解压rar文件怎么打开,java解压rar文件
- linux调用v4l2获取视频,嵌入式Linux:V4L2视频采集操作流程和接口说明
- io流图解 java_详细讲解JAVA中的IO流
- linux sudo 必须属于用户ID0,sudo:/usr/bin/sudo 务必属于用户 ID 0(的用户)并且设置 setuid 位...
- 前台提交数据到php mysql,建立一个基础的MySQL数据库,使用PHP来抓取和处理数据,并抛出给前台...
- 数据结构——二叉树的最长路径问题
- leetcote34. 在排序数组中查找元素的第一个和最后一个位置
- [JS-BOM]BOM_Location地址栏对象
- [C++11]独占的智能指针unique_ptr的初始化和使用