题目链接:戳我

非常不好意思,因为想要排版,所以今天先只把代码贴出来,明天补题解。

40pts暴力:直接暴力匹配

  #include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<cstdio>#define MAXN 100010using namespace std;int n,m;char s[MAXN];inline int solve(int l1,int r1,int l2,int r2){int cur_ans=0,maxx=0;for(int i=l1;i<=r1;i++){if(s[i]==s[l2+cur_ans]) cur_ans++;else cur_ans=0;maxx=max(maxx,cur_ans);//   printf("i=%d cur_ans=%d\n",i,cur_ans);if(cur_ans>=r2-l2+1) break;}return maxx;}int main(){#ifndef ONLINE_JUDGEfreopen("ce.in","r",stdin);#endifscanf("%d%d",&n,&m);scanf("%s",s+1);for(int i=1;i<=m;i++){int l1,l2,r1,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);printf("%d\n",solve(l1,r1,l2,r2));}return 0;}

开O2才能A的正解:SA+二分+二分+主席树
复杂度是两只log的。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define MAXN 200010
using namespace std;
int n,m,p,tot;
int sa[MAXN],rnk[MAXN],tax[MAXN],tp[MAXN];
int lg[MAXN],h[MAXN],rt[MAXN],st[MAXN][18];
char s[MAXN];
struct Node{int ls,rs,ff,cnt;}t[MAXN<<4];
inline void build(int &x,int f,int l,int r,int k)
{x=++tot;t[x]=t[f];t[x].cnt++;if(l==r) return;int mid=(l+r)>>1;if(k<=mid) build(t[x].ls,t[f].ls,l,mid,k);else build(t[x].rs,t[f].rs,mid+1,r,k);
}
inline int query(int x,int f,int l,int r,int ll,int rr)
{if(ll<=l&&r<=rr) return t[x].cnt-t[f].cnt;int mid=(l+r)>>1,cur_ans=0;if(ll<=mid) cur_ans+=query(t[x].ls,t[f].ls,l,mid,ll,rr);if(mid<rr) cur_ans+=query(t[x].rs,t[f].rs,mid+1,r,ll,rr);return cur_ans;
}
inline void q_sort()
{for(int i=1;i<=m;i++) tax[i]=0;for(int i=1;i<=n;i++) tax[rnk[i]]++;for(int i=1;i<=m;i++) tax[i]+=tax[i-1];for(int i=n;i>=1;i--) sa[tax[rnk[tp[i]]]--]=tp[i];
}
inline void suffix_sort()
{m=50,p=0;for(int i=1;i<=n;i++) rnk[i]=s[i]-'a'+1,tp[i]=i;q_sort();for(int w=1;p<n;m=p,w<<=1){p=0;for(int i=1;i<=w;i++) tp[++p]=n+i-w;for(int i=1;i<=n;i++) if(sa[i]-w>0) tp[++p]=sa[i]-w;q_sort();swap(rnk,tp);p=rnk[sa[1]]=1;for(int i=2;i<=n;i++)rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;}
}
inline void get_h()
{int j,k=0;for(int i=1;i<=n;i++){if(k) k--;int j=sa[rnk[i]-1];while(s[i+k]==s[j+k]) k++;h[rnk[i]]=k;}
}
inline void st_init()
{for(int i=1;i<=n;i++) st[i][0]=h[i];for(int j=1;j<=17;j++)for(int i=1;i<=n;i++)st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
inline int st_query(int l,int r)
{if(l==r) return 0x3f3f3f3f;l++;return min(st[l][lg[r-l+1]],st[r-(1<<lg[r-l+1])+1][lg[r-l+1]]);
}
inline bool check(int x,int l1,int r1,int l2,int r2)
{int L,R,l=1,r=rnk[l2],ans=r;while(l<=r){int mid=(l+r)>>1;if(st_query(mid,rnk[l2])>=x) ans=mid,r=mid-1;else l=mid+1;}L=ans;l=rnk[l2],r=n,ans=l;while(l<=r){int mid=(l+r)>>1;if(st_query(rnk[l2],mid)>=x) ans=mid,l=mid+1;else r=mid-1;}R=ans;return query(rt[R],rt[L-1],1,n,l1,r1-x+1)==0?false:true;
}
int main()
{#ifndef ONLINE_JUDGEfreopen("ce.in","r",stdin);#endifscanf("%d%d",&n,&m);scanf("%s",s+1);for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;suffix_sort();get_h();st_init();for(int i=1;i<=n;i++) build(rt[i],rt[i-1],1,n,sa[i]);for(int i=1;i<=m;i++){int l1,l2,r1,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);int ans=0;int l=0,r=min(r1-l1,r2-l2)+1;while(l<=r){int mid=(l+r)>>1;if(check(mid,l1,r1,l2,r2)) ans=mid,l=mid+1;else r=mid-1;}printf("%d\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/fengxunling/p/10884267.html

HEOI2016/TJOI2016 字符串问题相关推荐

  1. [HEOI2016/TJOI2016]字符串 (后缀数组+主席树+二分)

    description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为 n 的字符串 s,和 m 个问题.佳媛姐姐必须正确回答这 m 个问 ...

  2. 洛谷P4094 [HEOI2016/TJOI2016]字符串【后缀数组+主席树+st表】

    时空限制 2000ms / 256MB 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须正确 ...

  3. 主席树 + 后缀数组求LCP + 二分套二分 ---- P4094 [HEOI2016/TJOI2016]字符串

    题目链接 题目大意: 解题思路: 设我们的答案为midmidmid(注意这里有坑是[a,b][a,b][a,b]的所有子串和[c,d][c,d][c,d]这个子串的最长lcplcplcp),那么我们会 ...

  4. 洛谷 P4094 [HEOI2016/TJOI2016]字符串 后缀数组+二分+主席树

    题目链接 后缀数组 题目分析: sa[i] – 第i小的后缀的编号 rank[i] --编号为i的后缀排第几: height[i] – 第i和第i-1的最长lcp最长公共前缀: 1.二分答案,答案肯定 ...

  5. P4094 [HEOI2016/TJOI2016]字符串 [SA + 主席树]

    传送门 转换为判断,二分一个len,判断后缀起点在a -- b-mid+1 直接存不存在S, 使lcp(S,c)>= len,我们发现rank[S] 一定在c左右的一个范围内, 我们二分这个范围 ...

  6. P2825 [HEOI2016/TJOI2016]游戏

    题目描述 详见  P2825 [HEOI2016/TJOI2016]游戏. solution 套路题. 一般思路是行列建点跑二分图最大匹配. 此题中的#会分隔行列,因此我们把每行的极大联通块设为点,列 ...

  7. [HEOI2016/TJOI2016]求和(第二类斯特林数)

    题目 [HEOI2016/TJOI2016]求和 关于斯特林数与反演的更多姿势\(\Longrightarrow\)点这里 做法 \[\begin{aligned}\\ Ans&=\sum\l ...

  8. 洛谷P4094 - [TJOI2016]字符串

    Portal Description 给出一个字符串\(s(|s|\leq10^5)\)和\(m\)次询问,每次询问子串\(s[x_1..x_2]\)的所有子串和\(s[y_1..y_2]\)的最长公 ...

  9. 线段树分裂与合并 ----- P2824 [HEOI2016/TJOI2016]排序 [线段树分裂合并 OR 01序列排序+二分线段树]

    题目链接 题目大意: 对一个序列,每次按照升序或者降序排序序列某一段,问你最后的序列是什么? 解法1:二分+线段树 首先我们知道对一个01序列进行排序是很快的!我们只要知道里面有多少个1和多少个0,那 ...

最新文章

  1. 天天Linux-Ctrl+S快捷键锁定屏幕的问题
  2. Dart微基准测试第一部分
  3. Java 正青春:现状与技术趋势报告
  4. 25 Refs转发机制与在高阶组件中的使用
  5. 超4000人参加源码共读,喊你来一起学习成长~打开新世界
  6. 服务器iis自动停止,IIS应用程序池老是自动停止
  7. Hive编程指南pdf
  8. 计算机基础知识200分选择题,计算机基础考试题库及答案
  9. windows上编译,使用libtorrent
  10. django urls import views报错
  11. android 自动跳转市场,js判断设备,跳转app应用、android市场或者AppStore
  12. 向量ab怎么用计算机打出来,数学ab上面加一横线-数学符号如何打?急急急!!!向量AB上的剪 – 手机爱问...
  13. Cadence PCB仿真 使用Allegro PCB SI为BRD文件创建通用型IBIS模型的方法图文教程
  14. hydrus1d使用说明_Hydrus-1D中文说明.doc
  15. 打小都说我聪明,自从学了Linux,我才如梦初醒
  16. NancyFx系列之 Hello World
  17. 用Gzip进行js的超强压缩
  18. 【NOIP2014模拟】木马
  19. Python OpenCV绘画实现 油画效果、水彩效果
  20. java计算数据的百分比

热门文章

  1. mysql数据库sql语句大全
  2. 《数据分析实战 基于EXCEL和SPSS系列工具的实践》一第2章 数据分析的理论、工具、模型...
  3. Spring MVC - 配置Spring MVC
  4. Hibernate的数据查找,添加!
  5. Webservice开发流程
  6. 推荐12个Android开发源码(包括应用、游戏、效果等等)
  7. 企业网远程协助的小能手
  8. 五种JSP页面跳转方法详解
  9. opencv 图片读取和视频读取(一)
  10. Linux下l2tp客户端xl2tpd的安装配置