zoukankan      html  css  js  c++  java
  • [loj6031]字符串

    为了方便,用$N=10^{5}$来描述复杂度

    (对原串建立SAM)注意到$sum|w|=qkle N$,考虑对$q$和$k$的大小关系分类讨论:

    1.若$qle k$,即询问次数较少,将其与原串建立一个广义SAM,然后找到枚举所有区间,倍增找到该区间对应子串的位置,该right集合大小即为答案,时间复杂度为$o(qNlog N)$

    (建立广义SAM的实际操作,由于只关心于$s$的子串,并不需要新建节点,会更方便一些)

    2.若$k<q$,即串长较短,直接暴力枚举查询串的所有子串,并在原串的SAM上查询其出现次数(即对应节点的right集合大小),然后统计其在$[l_{a},r_{a}],[l_{a+1},r_{a+1}],...,[l_{b},r_{b}]$中出现了几次:

    将$m$个区间中相同区间存储位置到同一个vector中,然后即查询该区间对应的vector有几个元素在$[a,b]$中,通过二分即可,时间复杂度为$o(qk^{2}log N)=o(Nklog N)$

    显然总复杂度为$O(Nsqrt{N}log N)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define ll long long
     5 vector<int>v[N];
     6 int V,n,m,q,l,lst,a,b,nex[N],len[N],R[N],ch[N][26],A[N],B[N],pos[N],Len[N],fa[N][20];
     7 ll ans;
     8 char s[N],ss[N];
     9 void add(int c){
    10     int p=lst,np=lst=++V;
    11     len[np]=len[p]+1;
    12     while ((p)&&(!ch[p][c])){
    13         ch[p][c]=np;
    14         p=nex[p];
    15     }
    16     if (!p)nex[np]=1;
    17     else{
    18         int q=ch[p][c];
    19         if (len[q]==len[p]+1)nex[np]=q;
    20         else{
    21             int nq=++V;
    22             nex[nq]=nex[q];
    23             nex[q]=nex[np]=nq;
    24             len[nq]=len[p]+1;
    25             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    26             while ((p)&&(ch[p][c]==q)){
    27                 ch[p][c]=nq;
    28                 p=nex[p];
    29             }
    30         }
    31     }
    32 }
    33 void dfs(int k,int f){
    34     fa[k][0]=f;
    35     for(int i=1;i<20;i++)fa[k][i]=fa[fa[k][i-1]][i-1];
    36     for(int i=0;i<v[k].size();i++){
    37         dfs(v[k][i],k);
    38         R[k]+=R[v[k][i]];
    39     }
    40 }
    41 int get(int k,int l){
    42     for(int i=19;i>=0;i--)
    43         if (len[fa[k][i]]>=l)k=fa[k][i];
    44     return k;
    45 }
    46 int main(){
    47     scanf("%d%d%d%d%s",&n,&m,&q,&l,s);
    48     for(int i=0;i<m;i++)scanf("%d%d",&A[i],&B[i]);
    49     V=lst=1;
    50     for(int i=0;i<n;i++){
    51         add(s[i]-'a');
    52         R[lst]=1;
    53     }
    54     for(int i=2;i<=V;i++)v[nex[i]].push_back(i);
    55     dfs(1,0);
    56     if (q<=l){
    57         for(int ii=1;ii<=q;ii++){
    58             scanf("%s%d%d",ss,&a,&b);
    59             ans=0;
    60             for(int i=0,k=1;i<l;i++){
    61                 while ((k>1)&&(!ch[k][ss[i]-'a']))k=nex[k];
    62                 Len[i]=len[k];
    63                 if (i)Len[i]=min(Len[i],Len[i-1]);
    64                 if (ch[k][ss[i]-'a']){
    65                     k=ch[k][ss[i]-'a'];
    66                     Len[i]++;
    67                 }
    68                 pos[i]=k;
    69             }
    70             for(int j=a;j<=b;j++)
    71                 if (Len[B[j]]>=B[j]-A[j]+1)ans+=R[get(pos[B[j]],B[j]-A[j]+1)];
    72             printf("%lld
    ",ans);
    73         }
    74     }
    75     else{
    76         for(int i=0;i<l*l;i++)v[i].clear();
    77         for(int i=0;i<m;i++)v[A[i]*l+B[i]].push_back(i);
    78         for(int ii=1;ii<=q;ii++){
    79             scanf("%s%d%d",ss,&a,&b);
    80             ans=0;
    81             for(int i=0;i<l;i++)
    82                 for(int j=i,k=1;j<l;j++){
    83                     k=ch[k][ss[j]-'a'];
    84                     if (!k)break;
    85                     int p=i*l+j;
    86                     int posl=lower_bound(v[p].begin(),v[p].end(),a)-v[p].begin();
    87                     int posr=upper_bound(v[p].begin(),v[p].end(),b)-v[p].begin()-1;
    88                     ans+=(ll)R[k]*max(posr-posl+1,0);
    89                 }
    90             printf("%lld
    ",ans);
    91         }
    92     }
    93     return 0;
    94 } 
    View Code
  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15168887.html
Copyright © 2011-2022 走看看