zoukankan      html  css  js  c++  java
  • 清橙A1484

    http://www.tsinsen.com/ViewGProblem.page?gpid=A1484###

    题解:

      在线插入并不好做,我们将所有操作离线,变为删除操作。

      每次询问的时候对于当前B串所在起始位置及其长度向上向下二分,然后查询区间内合法的当前A串内的匹配点即可。

         用树状数组维护(不过我sb的写了线段树,后来才发现···)。

    code:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #define maxn 200005
      7 using namespace std;
      8 char ch,a[maxn*3],b[maxn*3],s[maxn];
      9 int n,m,q,la,ra,lb,rb,lena,lenb,op[maxn],st[18][maxn],ans[maxn];
     10 int SA[maxn],rank[maxn],sum[maxn],height[maxn],t1[maxn],t2[maxn];
     11 bool ok;
     12 void read(int &x){
     13     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     14     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     15     if (ok) x=-x;
     16 }
     17 struct seg{
     18     #define ls k<<1
     19     #define rs (k<<1)+1
     20     int val[maxn<<2];
     21     void build(int k,int l,int r){
     22         if (l==r){
     23             if (SA[l]<=ra) val[k]=1;
     24             return;
     25         }
     26         int m=(l+r)>>1;
     27         build(ls,l,m),build(rs,m+1,r);
     28         val[k]=val[ls]+val[rs];
     29     }
     30     void modify(int k,int l,int r,int x,int add){
     31         if (l==r){val[k]+=add;return;}    
     32         int m=(l+r)>>1;
     33         if (x<=m) modify(ls,l,m,x,add);
     34         else modify(rs,m+1,r,x,add);
     35         val[k]=val[ls]+val[rs];
     36     }
     37     int query(int k,int l,int r,int x,int y){
     38         if (l==x&&r==y) return val[k];
     39         int m=(l+r)>>1;
     40         if (y<=m) return query(ls,l,m,x,y);
     41         else if (x<=m) return query(ls,l,m,x,m)+query(rs,m+1,r,m+1,y);
     42         else return query(rs,m+1,r,x,y);
     43     }
     44 }T;
     45 void get_SA(){
     46     int *x=t1,*y=t2,tot=0; m=255;
     47     for (int i=1;i<=n;i++) sum[x[i]=s[i]]++;
     48     for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
     49     for (int i=n;i>=1;i--) SA[sum[x[i]]--]=i;
     50     for (int len=1;tot<n;len<<=1,m=tot){
     51         tot=0;
     52         for (int i=n-len+1;i<=n;i++) y[++tot]=i;
     53         for (int i=1;i<=n;i++) if (SA[i]>len) y[++tot]=SA[i]-len;
     54         for (int i=1;i<=m;i++) sum[i]=0;
     55         for (int i=1;i<=n;i++) sum[x[y[i]]]++;
     56         for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
     57         for (int i=n;i>=1;i--) SA[sum[x[y[i]]]--]=y[i];
     58         swap(x,y),x[SA[1]]=tot=1;
     59         for (int i=2;i<=n;i++){
     60             if (y[SA[i]]!=y[SA[i-1]]||y[SA[i]+len]!=y[SA[i-1]+len]) tot++;
     61             x[SA[i]]=tot;
     62         }
     63     }
     64     for (int i=1;i<=n;i++) rank[i]=x[i];
     65 }
     66 void get_height(){
     67     for (int i=1,j=0;i<=n;i++){
     68         if (rank[i]==1) continue;
     69         while (s[i+j]==s[SA[rank[i]-1]+j]) j++;
     70         height[rank[i]]=j;
     71         if (j>0) j--;
     72     }
     73 }
     74 void prepare(){
     75     for (int i=1;i<=n;i++) st[0][i]=height[i];
     76     for (int i=1;i<=17;i++)
     77         for (int j=1;j<=n;j++){
     78             st[i][j]=st[i-1][j];
     79             if (j+(1<<(i-1))<=n) st[i][j]=min(st[i][j],st[i-1][j+(1<<(i-1))]);
     80         }
     81     T.build(1,1,n);
     82 }
     83 int calc(int l,int r){
     84     if (l>r) swap(l,r);
     85     int t=0; l++;
     86     if (l==r) return height[l];
     87     for (;l+(1<<t)<r;t++);
     88     if (l+(1<<t)>r) t--;
     89     return min(st[t][l],st[t][r-(1<<t)+1]);
     90 }
     91 int find(int s,int x,int op){
     92     int l,r,m;
     93     if (op) l=s,r=n;else l=1,r=s;
     94     while (l!=r){
     95         m=((l+r)>>1)+op;
     96         if (calc(m,s)<x){
     97             if (op) r=m-1;
     98             else l=m+1;
     99         }
    100         else{
    101             if (op) l=m;
    102             else r=m;
    103         }
    104     }
    105     return l;
    106 }
    107 int query(){
    108     int x=find(rank[lb],rb-lb+1,0),y=find(rank[lb],rb-lb+1,1);
    109     return T.query(1,1,n,x,y);
    110 }
    111 int main(){
    112     scanf("%s%s",a+maxn,b+maxn);
    113     la=ra=maxn,lb=rb=maxn;
    114     for (;a[ra];ra++); ra--;
    115     for (;b[rb];rb++); rb--;
    116     read(q);
    117     for (int i=1;i<=q;i++){
    118         read(op[i]);
    119         if (op[i]==1) a[--la]=getchar();
    120         else if (op[i]==2) a[++ra]=getchar();
    121         else if (op[i]==3) b[--lb]=getchar();
    122         else if (op[i]==4) b[++rb]=getchar();
    123     }
    124     for (int i=la;i<=ra;i++) s[++n]=a[i];
    125     lena=ra-la+1,la=1,ra=lena;
    126     s[++n]='#';
    127     int tmp=n+1;
    128     lenb=rb-lb+1;
    129     for (int i=lb;i<=rb;i++) s[++n]=b[i];
    130     lb=tmp,rb=lb+lenb-1;
    131     get_SA(),get_height(),prepare();
    132     for (int i=1;i<lenb;i++) T.modify(1,1,n,rank[ra--],-1);
    133     for (int i=q;i>=1;i--){
    134         if (op[i]==1) T.modify(1,1,n,rank[la++],-1);
    135         else if (op[i]==2) T.modify(1,1,n,rank[ra--],-1);
    136         else if (op[i]==3) T.modify(1,1,n,rank[++ra],1),lb++;
    137         else if (op[i]==4) T.modify(1,1,n,rank[++ra],1),rb--;
    138         else ans[i]=query();
    139     }
    140     for (int i=1;i<=q;i++) if (op[i]==5) printf("%d
    ",ans[i]);
    141     return 0;
    142 } 
  • 相关阅读:
    Firefox常用web开发插件
    引用MFC指针的获取(转载)
    J2EE的13种核心技术(转载)
    用Visio画ER图的解决方案(转载)
    [导入]六一
    [导入]独自等待
    [导入]随想
    [导入]小聚
    [导入]网站需求分析
    [导入]如何做好网站开发项目需求分析
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4731854.html
Copyright © 2011-2022 走看看