码迷,mamicode.com
首页 > 其他好文 > 详细

清橙A1484

时间:2015-08-15 10:16:18      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

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\n",ans[i]);
141     return 0;
142 } 

 

清橙A1484

标签:

原文地址:http://www.cnblogs.com/chenyushuo/p/4731854.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!