【BZOJ4453】cys就是要拿英魂!

Description

pps又开始dota视频直播了!一群每天被pps虐的蒟蒻决定学习pps的操作技术,他们把pps在这局放的技能记录了下来,每个技能用一个字符表示。经过研究,蒟蒻们发现字典序更大的连招威力更大。于是所有蒟蒻都想学习pps最强的连招。但是他们太弱了,不能学会整个视频里的连招,只能学会陈老师一段区间间内的连招,可是这个他们求不出,于是只好向你求助。为了蒟蒻们不再被pps虐(怎么可能),请你帮帮他们。简化题意:给你一个字符串,每次询问你一段区间的字典序最大的子串。

Input

第一行是一个字符串S,表示pps放的技能
第二行一个正整数Q,表示询问个数
接下来Q行,每行两个正整数[l,r],表示询问区间[l,r]中的字典序最大的子串。

Output

Q行,每行一个正整数,表示该区间内字典序最大的子串的起始位置。

Sample Input

Lets_go_mod_p!
5
2 2
3 3
2 5
1 10
2 9

Sample Output

2
3
3
3
3
数据范围:
1<=|S|<=100000
1<=Q<=100000
1<=l<=r<=|S|

题解:看到题,想都不用想一定是后缀数组+离线乱搞。然后就越搞越复杂。这里还是直接贴正解好了。

注释:

这里实际上是用单调栈优化set,不要搞反。

标算的核心就是那个删除时刻的标记,还有那个“伴随”概念。更具体的做法是,我们对于每个点维护两套边,一套指向的是:有哪些点的删除标记是当前点,另一套指向的是:有哪些点伴随当前点。(形成了一个类似森林的结构?)这样,我们枚举那些删除树上的点,再DFS下去,删除所有伴随树上的点就行了。

后缀数组的LCP不要写错啊啊啊~调了好久。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
const int maxn=100010;
int n,m,top,cnt;
int ra[maxn],rb[maxn],st[maxn],r[maxn],sa[maxn],rank[maxn],h[maxn],f[maxn][20],sta[maxn];
int Log[maxn],ans[maxn],to[maxn<<1],next[maxn<<1],hb[maxn],hd[maxn],del[maxn];
char str[maxn];
set<int> s;
struct QUERY
{int ql,qr,org;
}q[maxn];
int rd()
{int ret=0,f=1;   char gc=getchar();while(gc<'0'||gc>'9')  {if(gc=='-')f=-f;  gc=getchar();}while(gc>='0'&&gc<='9')  ret=ret*10+gc-'0',gc=getchar();return ret*f;
}
bool cmp(QUERY a,QUERY b)
{return a.qr<b.qr;
}
void build()
{n++;int i,j,k,p,*x=ra,*y=rb;for(i=0;i<n;i++) st[x[i]=r[i]]++;for(i=1;i<m;i++)   st[i]+=st[i-1];for(i=n-1;i>=0;i--)   sa[--st[x[i]]]=i;for(j=p=1;p<n;m=p,j<<=1){for(p=0,i=n-j;i<n;i++)   y[p++]=i;for(i=0;i<n;i++)  if(sa[i]>=j)    y[p++]=sa[i]-j;for(i=0;i<m;i++)    st[i]=0;for(i=0;i<n;i++) st[x[y[i]]]++;for(i=1;i<m;i++)  st[i]+=st[i-1];for(i=n-1;i>=0;i--)   sa[--st[x[y[i]]]]=y[i];for(swap(x,y),x[sa[0]]=0,i=p=1;i<n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j])?p-1:p++;}for(i=1;i<n;i++)   rank[sa[i]]=i;for(i=k=0;i<n-1;h[rank[i++]]=k)for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);n--;for(i=1;i<=n;i++)   f[i][0]=h[i];for(i=2;i<=n;i++)  Log[i]=Log[i>>1]+1;for(j=1;(1<<j)<=n;j++)  for(i=1;i+(1<<j)-1<=n;i++)    f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);
}
int getlcp(int a,int b)
{a=rank[a],b=rank[b];if(a>b)   swap(a,b);a++;int k=Log[b-a+1];return min(f[a][k],f[b-(1<<k)+1][k]);
}
void add(int c,int a,int b)
{if(a>=n)   return ;to[cnt]=b;if(c)    next[cnt]=hb[a],hb[a]=cnt++;else    next[cnt]=hd[a],hd[a]=cnt++;
}
void dfs(int x)
{del[x]=1,s.erase(x);for(int i=hb[x];i!=-1;i=next[i])   if(!del[to[i]]) dfs(to[i]);
}
void ins(int x)
{int i;while(top){if(rank[sta[top]]<rank[x]) add(0,x+getlcp(sta[top],x),sta[top]),add(1,x,sta[top]),top--;else  break;}sta[++top]=x,s.insert(x);for(i=hd[x];i!=-1;i=next[i])  if(!del[to[i]]) dfs(to[i]);
}
int main()
{memset(hb,-1,sizeof(hb));memset(hd,-1,sizeof(hd));scanf("%s",str),n=strlen(str);int i,j;for(i=0;i<n;i++)  r[i]=str[i],m=max(m,r[i]+1);build();m=rd();for(i=1;i<=m;i++) q[i].ql=rd()-1,q[i].qr=rd()-1,q[i].org=i;sort(q+1,q+m+1,cmp);for(i=1,j=0;i<=m;i++){for(;q[i].qr>=j;j++) ins(j);ans[q[i].org]=*(s.lower_bound(q[i].ql));}for(i=1;i<=m;i++)   printf("%d\n",ans[i]+1);return 0;
}

转载于:https://www.cnblogs.com/CQzhangyu/p/7095317.html

【BZOJ4453】cys就是要拿英魂! 后缀数组+单调栈+set相关推荐

  1. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  2. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  3. BZOJ3879: SvT【后缀数组+单调栈】

    Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...

  4. POJ - 3415 Common Substrings(后缀数组+单调栈)

    题目链接:点击查看 题目大意:给出两个字符串,再给出一个k,问两个字符串中长度大于等于k的公共子串有多少个(种类可重复) 题目分析:因为涉及到了子串问题,先用后缀数组跑出height数组来,接下来如果 ...

  5. [bzoj3238]差异(后缀数组+单调栈)

    显然我们可以先把len(Ti)+len(Tj)的值先算出来,再把LCP减去.所有len(Ti)+len(Tj)的值为n*(n-1)*(n+1)/2,这个随便在纸上画一画就可以算出来的. 接下来问题就是 ...

  6. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]

    题目地址 - GO-> 题目大意: 给定一个长度为 nn 的字符串SS,令TiTi表示它从第ii个字符开始的后缀,求以下这个式子的值: ∑1≤i<j≤nlen(Ti)+len(Tj)−2× ...

  7. 【BZOJ3879】SvT,后缀数组+单调栈维护sum

    Time:2016.08.15 Author:xiaoyimi 转载注明出处谢谢 如果有不明白的地方可以在下面评论问我 传送门 思路: 建立后缀数组求出Height 如果说对每次询问暴力求LCP累加的 ...

  8. POJ 3415 后缀数组+单调栈

    题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...

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

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

  10. 【HAOI2016/BZOJ4566】找相同字符 后缀数组+单调栈

    原题走这里 鉴于我实在不是很懂单调栈和单调队列这一系列东西,所以我决定稍微具体讲一下单调栈. 恩,本题实质上就是求两个字符串的公共子串数,其中只要出现位置不同,就算是不同的子串. 处理多个字符串的经典 ...

最新文章

  1. Android AOSP 单独编译某一模块
  2. try catch finally 执行顺序问题
  3. python 手动读取cifar10_Python搞定Excel,秒解决!大大提高工作效率
  4. web前端常用知识点
  5. 工作239:内容过长省略号失败 直接改的样式表
  6. unity中Animation与Animator的区别
  7. 【Flink】FLink checkpont 界面显示的含义
  8. wepy 父调用子组件方法_wepy踩坑小记(一)
  9. php连接mysql数据没反应_php无法连接mysql数据库的正确解决方法
  10. 深度学习和机器学习的相关资料
  11. usaco Raucous Rockers
  12. 【python】列表元素统计
  13. 如何给PDF加密码保护?这3种方法总有一个能用上
  14. 【20170706】保卫萝卜
  15. Hadoop LZO压缩配置
  16. 【SQL Server】数据库开发指南(二)MSSQL数据库开发对于库、表、数据类型、约束等相关操作
  17. html怎么转换小数点,在HTML5数字input(客户端)中强制小数点而不是逗号
  18. JAVASE——2.IO流
  19. 熬夜的T哥们T姐们注意了
  20. 科研笔记(五) SLAC WiFi Fingerprint+ Step counter融合定位

热门文章

  1. ue4 射线Trace Responses(踪迹响应)
  2. Crashing Balloon
  3. java随机发扑克牌程序,java_扑克牌小程序
  4. 一个屌丝程序员的青春(二一一)
  5. 假面骑士鸿蒙系统,《假面骑士》街机游戏,这样组合太棒了!
  6. 2021-2027全球与中国TAC功能膜市场现状及未来发展趋势
  7. mongodb分片集群数据库安全认证
  8. react仿钉钉流程图-审批工作流
  9. 以太网卡 及 以太网帧
  10. 2022-2028全球造水机市场现状及未来发展趋势