HEOI2016/TJOI2016 字符串问题

题目链接:戳我

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

40pts暴力:直接暴力匹配

  #include<iostream>
  #include<cstring>
  #include<algorithm>
  #include<cmath>
  #include<cstdio>
  #define MAXN 100010
  using 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_JUDGE
      freopen("ce.in","r",stdin);
      #endif
      scanf("%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_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%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

时间: 2024-11-13 03:32:08

HEOI2016/TJOI2016 字符串问题的相关文章

[LuoguP4094] [HEOI2016] [TJOI2016]字符串(二分答案+后缀数组+ST表+主席树)

[LuoguP4094] [HEOI2016] [TJOI2016]字符串(二分答案+后缀数组+ST表+主席树) 题面 给出一个长度为\(n\)的字符串\(s\),以及\(m\)组询问.每个询问是一个四元组\((a,b,c,d)\),问\(s[a,b]\)的所有子串和字符串\(s[c,d]\)的最长公共前缀长度的最大值. \(n,m \leq 10^5\) 分析 显然答案有单调性.首先我们二分答案\(mid\),考虑如何判定. 如果mid这个答案可行,那么一定存在一个后缀x,它的开头在\([a,

[HEOI2016/TJOI2016]字符串

题解: 一道挺水的题目 首先暴力是nm的 后缀数组o(1)判断 然后考虑一下正解: 首先跟后缀数组有关先考虑下二分答案.. 然后再二分出rank与它相邻多少的后缀能满足条件 然后查找一下当前区间(注意右端点是n-k+1)是否存在rank在这一大小范围的数 这个主席数维护一下就可以了 原文地址:https://www.cnblogs.com/yinwuxiao/p/8850266.html

【[HEOI2016/TJOI2016]字符串】

码农题啊 上来先无脑一个\(SA\)的板子,求出\(SA\)和\(het\)数组 我们只需要从\(sa[i]\in[a,b]\)的所有\(i\)中找到一个\(i\)使得\(sa[i]\)和\(rk[c]\)之间的最小值最大就好了 但是还必须得满足\(sa[i]+lcp-1<=b\),毕竟整个串还得在\([a,b]\)内部 考虑一下二分答案 根据\(het\)数组的性质显然越靠近\(rk[c]\)的\(sa[i]\)形成的\(lcp\)越长,于是我们可以利用一个\(ST\)表加二分找到从\(rk[

P4094 [HEOI2016/TJOI2016]字符串

题意 考虑二分答案\(mid\),现在我们要判断\(s[c...c+mid-1]\)是否在\(s[a...b]\)出现过. 首先找到\(s[c...c+mid-1]\)所在的状态: 建出\(parent\ tree\),从\(s[1...c+mid-1]\)的节点(这个可以记录)用倍增向上跳到最后一个\(len\geqslant mid\)的节点即可,记这个节点为\(now\). 之后我们要判断\(now\)的\(endpos\)中是否含有\([a+mid-1,b]\)中的某个数,我们给每个节点

[HEOI2016/TJOI2016]排序 解题报告

[HEOI2016/TJOI2016]排序 题意 给出一个大小为 \(n\) 的排列, 对这个排列进行 \(m\) 次操作, 操作分为以下两种, 0 l r 表示将区间 \([l,r]\) 的数升序排序. 1 l r 表示将区间 \([l,r]\) 的数降序排序. 询问 \(m\) 次操作后下标为 \(q\) 的数字. 思路 不看题解打死也想不出来系列 考虑二分答案. 设当前二分的答案为 \(mid\), 把原排列中 大于等于 \(mid\) 的数标记为 \(1\), 小于 \(mid\) 的数

dtoj4542. 「TJOI / HEOI2016」字符串

4542. 「TJOI / HEOI2016」字符串 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为 $ n $ 的字符串 $ s $,和 $ m $ 个问题.佳媛姐姐必须正确回答这 $ m $ 个问题,才能打开箱子拿到礼物,升职加薪,出任 CEO,嫁给高富帅,走上人生巅峰.每个问题均有 $a, b, c, d$ 四个参数,问你子串 $s[a \ldots b]$ 的所有子串和 $s[c \ldots d]$ 的最长公共前缀的长度的最

bzoj4556【TJOI2016&amp;HEOI2016】字符串

4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 195  Solved: 103 [Submit][Status][Discuss] Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CE O,嫁给高富帅,走上人生

[HEOI2016/TJOI2016]排序

4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec Memory Limit: 256 MB Submit: 2366 Solved: 1188 [Submit][Status][Discuss] Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排 序分为两种:1:(0,l,

[HEOI2016&amp;TJOI2016] 排序(线段树)

4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2703  Solved: 1386[Submit][Status][Discuss] Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排 序分为两种:1:(0,l,