题解:神题.....一眼看过去完全不知道怎么维护字典序最大

突破口在....离线所有询问从左往右加入后缀  然后对于三种情况分别讨论

    当$ i<j $

    若$ rank2[i]>rank2[j] $  那么i最优性继续保持

    若$  rank2[i]<rank2[j] $  这里分情况讨论的是

    $  i+lcp(i,j)-1>=j $  这里i的最优性继续保持  只有当j超过了 $ i+lcp(i,j)-1 $时  i将丧失优势

因此我们用单调栈来维护 在j之前rank2小于j的位置  然后将删除标记打到他被删除的时刻   即当访问到删除时刻时  它及其子树都将被删除 还要注意的是  i位置依赖于j位置 若j位置在接下来的某个时刻丧失了优势  那么i同样会被删除掉  查询的话就是当前查询左端点的后继节点(具体看代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=HH[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=3e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*HH[MAXN],*o=e;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=HH[x];HH[x]=o++;}
ll read(){ll x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*f;
}
bool cmp(int t[],int f,int w,int k){return t[f]==t[w]&&t[f+k]==t[w+k];}
int sa[MAXN],rank1[MAXN],rank2[MAXN],t1[MAXN],t2[MAXN],txt[MAXN],td[MAXN];
void Sa(char str[]){int len=strlen(str);int m=250;int *td=t1;int *rank1=t2;for(int i=0;i<m;i++)txt[i]=0;for(int i=0;i<len;i++)txt[str[i]]++,rank1[i]=str[i];for(int i=1;i<m;i++)txt[i]+=txt[i-1];for(int i=len-1;i>=0;i--)sa[--txt[str[i]]]=i;for(int k=1;k<=len;k=k*2){int p=0;for(int i=len-k;i<len;i++)td[p++]=i;for(int i=0;i<len;i++)if(sa[i]>=k)td[p++]=sa[i]-k;for(int i=0;i<m;i++)txt[i]=0;for(int i=0;i<len;i++)txt[rank1[i]]++;for(int i=1;i<m;i++)txt[i]+=txt[i-1];for(int i=len-1;i>=0;i--)sa[--txt[rank1[td[i]]]]=td[i];swap(rank1,td);rank1[sa[0]]=0;p=1;for(int i=1;i<len;i++)rank1[sa[i]]=cmp(td,sa[i],sa[i-1],k)?p-1:p++;if(p==len)return ;m=p;}
}
int H[MAXN],h[MAXN];
void hh(char str[]){int len=strlen(str);memset(h,0,sizeof(h));memset(H,0,sizeof(H));for(int i=0;i<len;i++)rank2[sa[i]]=i;for(int i=0;i<len;i++){if(rank2[i]==0)continue;int t=sa[rank2[i]-1];int w=i;int k;if(i==0||H[i-1]<=1)k=0;else k=H[i-1]-1,t+=k,w+=k;while(t<len&&w<len){if(str[t]==str[w])k++;else break;t++;w++;}H[i]=k;h[rank2[i]]=k;}
}
int dp[MAXN][21];int ma[MAXN];
void St(char str[]){ma[0]=-1;for(int i=1;i<MAXN;i++)if((i&(i-1))==0)ma[i]=ma[i-1]+1;else ma[i]=ma[i-1];int len=strlen(str);for(int i=1;i<len;i++)dp[i][0]=h[i];for(int j=1;(1<<(j-1))<=len;j++){for(int i=1;i+(1<<j)<=len;i++){dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);}}
}
int rmq(int l,int r){if(l>r)swap(l,r);l++;int k=ma[r-l+1];int k1=(1<<k);return min(dp[l][k],dp[r-k1+1][k]);
}char str[MAXN];
typedef struct node{int l,r,id;friend bool operator<(node aa,node bb){return aa.r<bb.r;}
}node;
node que[MAXN];
set<int>s;
int ans[MAXN];
vector<int>vec[MAXN];
bool vis[MAXN];
int st[MAXN],tot;void del(int x){vis[x]=1;s.erase(s.lower_bound(x));link(x){if(!vis[j->t])del(j->t);}
}void solve(int t,int len){while(tot&&rank2[st[tot]]<rank2[t]){int x=rmq(rank2[st[tot]],rank2[t]);if(t+x<len)vec[t+x].pb(st[tot]);add(x,st[tot],0);tot--;}st[++tot]=t;s.insert(t);for(int i=0;i<vec[t].size();i++)if(!vis[vec[t][i]])del(vec[t][i]);
}int main(){scanf("%s",str);int len=strlen(str);str[len]='!';Sa(str);hh(str);St(str);int n=read();inc(i,1,n)que[i].l=read(),que[i].r=read(),que[i].id=i;sort(que+1,que+n+1);int r=0;inc(i,1,n){while(r<len&&r+1<=que[i].r)solve(r,len),r++;ans[que[i].id]=(*(s.lower_bound(que[i].l-1)));}inc(i,1,n)printf("%d\n",ans[i]+1);
}

  

4453: cys就是要拿英魂!

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 213  Solved: 104
[Submit][Status][Discuss]

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|

转载于:https://www.cnblogs.com/wang9897/p/10357031.html

[BZOJ]4453: cys就是要拿英魂!相关推荐

  1. ●BZOJ 4453 cys就是要拿英魂!

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4453 题解: 后缀数组,离线询问,栈 看了一堆题解才看懂,太弱啦 ~ 如果对于一个区间[l, ...

  2. bzoj4453: cys就是要拿英魂!(后缀数组+单调栈+set)

    传送门 stOstOstO 神题 OrzOrzOrz 题意: 给定一个串S,有Q个询问,每次问一个区间内字典序最大的子串. |S|,Q<=10^5,可以离线! 大佬的题解: 代码: #inclu ...

  3. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  4. S-T平面图中利用最短路求最小割(BZOJ 1001)

    BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...

  5. BZOJ 1124: [POI2008]枪战Maf(构造 + 贪心)

    题意 有 \(n\) 个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪. 因此,对于不同的开枪顺序,最后死的人也不同. 问最 ...

  6. BZOJ 2957楼房重建

    传送门 线段树 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include< ...

  7. BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)

    BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...

  8. bzoj 4871: [Shoi2017]摧毁“树状图”

    4871: [Shoi2017]摧毁"树状图" Time Limit: 25 Sec  Memory Limit: 512 MB Submit: 53  Solved: 9 [Su ...

  9. BZOJ 1592. Making the Grade(思维,数据结构优化DP,以及三个拓展问题)[Usaco2008 Feb]【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 BZOJ简单题合集x 目录 BZOJ 1592. Making the Grade 拓展问题一 拓展问 ...

  10. BZOJ 1590.Secret Message 秘密信息(Trie树) [Usaco2008 Dec]【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 BZOJ简单题合集x Weblink https://hydro.ac/d/bzoj/p/1590 P ...

最新文章

  1. 用选框工具画圆角矩形
  2. 非法控制计算机信息系统罪的标准,非法获取计算机信息系统数据、非法控制计算机信息系统罪立案标准...
  3. MATLAB Tick的方向(刻度标外翻)
  4. 百度鹰眼ajax 坐标转换,Web服务更新日志
  5. 最流行的 6 款 Python 解释器
  6. 前端实现图片或视频预览的3种方法
  7. 阿里云ace考试有什么用?想要通过需要掌握哪些方面知识?
  8. bat脚本 - 通过bat脚本一键启动[开机启动]日常应用
  9. python数字的表示
  10. 2003服务器开机无限重启,Windows2003 系统自动重启
  11. (1)在ensp上面进行静态路由和默认路由测试(直接上手)
  12. 解决日志打印过多问题
  13. python安装osgeo及shapefile库、is not a supported wheel on this platform 的问题
  14. python c++情侣网名是什么意思_网友:c++与Python,究竟谁才是大哥?
  15. 联想xt92耳机测评
  16. 空客为重庆四条地铁线路部署TETRA系统 助力实施跨线运营
  17. outlook邮件内容丢失与Mail API异常
  18. Linux:MySQL:重启服务细节
  19. 《MATLAB 入门之旅》知识点总结
  20. Unity使用材质球使图片发光

热门文章

  1. VM虚拟机分区硬盘/安装win10系统
  2. java标签用setbounds_setBounds的用法
  3. “山巅一寺一壶酒”——圆周率的谐音记忆法
  4. 丧心病狂的Monkey测试
  5. 4.Linux本地yum源仓库安装配置
  6. 【问题征集】向 iPod 之父、iPhone 联合设计者、Google Nest 创始人 Tony Fadell 提问啦
  7. 吊打面试官系列之:UI自动化面试题汇总,对标P7,从此再也不怕面试官了。
  8. CMakeLists.txt文本编辑工具
  9. 基于Vue的标尺插件(刻度尺)
  10. java 接收 gprs通信_java 接收GPRS数据