A1484. two strings(罗干)

时间限制:1.0s   内存限制:256.0MB
【问题描述】
  给定两个字符串A和B,有五种操作,操作1为在A串开头添加一个字符,操作2为在A串结尾添加一个字符,操作3为在B串开头添加一个字符,操作4为在B串结尾添加一个字符,操作5为询问当前的B串在当前A串中出现的次数。保证字符均为小写字母,且A、B串初始非空。
【输入格式】
  第一行第二行分别为初始的A串和B串;
  第三行一个整数m,表示操作的次数;
  接下来m行,每行表示一个操作,每行第一个数为一个在1-5之间的数字,若其值不为5,则在数字后会有一个小写字母。
【输出格式】
  对于每个询问,每行输出一个整数,表示B串在A串中出现的次数。
【样例输入】
  ababc
  a
  7
  5
  4 b
  5
  3 a
  1 a
  5
  5
【样例输出】
  2
  2
  1
  1
【数据规模】
  10%的数据中,最终A串和B串长度之和小于等于200,操作数小于等于10。
  30%的数据中,最终A串和B串长度之和小于等于2000,操作数小于等于1000。
  100%的数据中,最终A串和B串长度之和小于等于200000,操作数小于等于200000。
分析:对最终的A串和B串用分隔符拼接,构建后缀数组,模拟这m次操作;
   可以发现对于在A串或B串添加字符,最多会影响一个位置的可行性;
   在后缀数组中查找字符串可以使用二分找到连续区间,询问区间的合法性可以使用树状数组实现;
代码:
  

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+,inf=0x3f3f3f3f;
int n,m,k,t,d[maxn],tot;
void add(int x,int y){while(x<=tot)d[x]+=y,x+=x&(-x);}
int get(int x){int ret=;while(x)ret+=d[x],x-=x&(-x);return ret;}
struct query{int op,pos;}q[maxn];
struct node{int x,id,nt;}e[maxn];
char ch[maxn];
int cntA[maxn],cntB[maxn];
int sa[maxn],lev[maxn],height[maxn];
int A[maxn],B[maxn],tsa[maxn];
int mi[][maxn],p[maxn];
int ask(int l,int r)
{
int x=p[r-l+];
return min(mi[x][l],mi[x][r-(<<x)+]);
}
void solve(int n,int m)
{
for (int i = ; i < m; i ++) cntA[i] = ;
for (int i = ; i <= n; i ++) cntA[ch[i]] ++;
for (int i = ; i < m; i ++) cntA[i] += cntA[i - ];
for (int i = n; i; i --) sa[cntA[ch[i]] --] = i;
lev[sa[]] = ;
for (int i = ; i <= n; i ++)
{
lev[sa[i]] = lev[sa[i - ]];
if (ch[sa[i]] != ch[sa[i - ]]) lev[sa[i]] ++;
}
for (int l = ; lev[sa[n]] < n; l <<= )
{
memset(cntA,,sizeof(cntA[])*(n+));
memset(cntB,,sizeof(cntB[])*(n+));
for (int i = ; i <= n; i ++)
{
cntA[A[i] = lev[i]] ++;
cntB[B[i] = (i + l <= n) ? lev[i + l] : ] ++;
}
for (int i = ; i <= n; i ++) cntB[i] += cntB[i - ];
for (int i = n; i; i --) tsa[cntB[B[i]] --] = i;
for (int i = ; i <= n; i ++) cntA[i] += cntA[i - ];
for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i];
lev[sa[]] = ;
for (int i = ; i <= n; i ++)
{
lev[sa[i]] = lev[sa[i - ]];
if (A[sa[i]] != A[sa[i - ]] || B[sa[i]] != B[sa[i - ]]) lev[sa[i]] ++;
}
}
for (int i = , j = ; i <= n; i ++)
{
if (j) j --;
while (ch[i + j] == ch[sa[lev[i] - ] + j]) j ++;
height[lev[i]] = j;
}
}
int main() {
int i,j;
//freopen("in.txt","r",stdin);
tot=;
int ha=-,ta=-,hb=-,tb=-;
scanf("%s",ch+);
for(i=;ch[i];i++)
{
e[tot].x=ch[i]-'a';
if(!~ha)ha=ta=tot;
else e[ta].nt=tot,ta=tot;
tot++;
}
scanf("%s",ch+);
for(i=;ch[i];i++)
{
e[tot].x=ch[i]-'a';
if(!~hb)hb=tb=tot;
else e[tb].nt=tot,tb=tot;
tot++;
}
//cout<<ha<<" "<<ta<<" "<<hb<<" "<<tb<<endl;
scanf("%d",&m);
for(i=;i<=m;i++)
{
int op;
char str[];
scanf("%d",&op);
q[i].op=op;
if(op==)continue;
scanf("%s",str);
e[tot].x=str[]-'a';
e[tot].id=i;
if(op==)
{
e[tot].nt=ha;
ha=tot;
}
else if(op==)
{
e[ta].nt=tot;
ta=tot;
}
else if(op==)
{
e[tot].nt=hb;
hb=tot;
}
else if(op==)
{
e[tb].nt=tot;
tb=tot;
}
tot++;
}
tot=;
int sx,sy,ex,ey;
sx=sy=-;
for(i=ha;;i=e[i].nt)
{
ch[++tot]=e[i].x;
if(e[i].id)q[e[i].id].pos=tot;
else {if(!~sx)sx=tot;ex=tot;}
if(i==ta)break;
}
ch[++tot]=;
for(i=hb;;i=e[i].nt)
{
ch[++tot]=e[i].x;
if(e[i].id)q[e[i].id].pos=tot;
else {if(!~sy)sy=tot;ey=tot;}
if(i==tb)break;
}
solve(tot,);
for(i=;i<=tot;i++)p[i]=+p[i>>];
for(i=;<<i<=tot;i++)
{
for(j=;j+(<<i)<=tot;j++)
{
if(!i)mi[i][j]=height[j];
else mi[i][j]=min(mi[i-][j],mi[i-][j+(<<(i-))]);
}
}
//cout<<sx<<" "<<ex<<" "<<sy<<" "<<ey<<endl;
for(i=sx;i+ey-sy<=ex;i++)add(lev[i],);
for(i=;i<=m;i++)
{
int op=q[i].op;
if(op==)
{
sx--;
if(sx+ey-sy<=ex)add(lev[sx],);
}
else if(op==)
{
ex++;
if(sx+ey-sy<=ex)add(lev[ex-ey+sy],);
}
else if(op==)
{
sy--;
if(ex-ey+sy+>=sx)add(lev[ex-ey+sy+],-);
}
else if(op==)
{
ey++;
if(ex-ey+sy+>=sx)add(lev[ex-ey+sy+],-);
}
else
{
int pos=lev[sy],len=ey-sy+;
int l=,r=pos-,pl=pos,pr=pos;
while(l<=r)
{
int mid=l+r>>;
if(ask(mid+,pos)>=len)pl=mid,r=mid-;
else l=mid+;
}
l=pos+,r=tot;
while(l<=r)
{
int mid=l+r>>;
if(ask(pos+,mid)>=len)pr=mid,l=mid+;
else r=mid-;
}
printf("%d\n",get(pr)-get(pl-));
}
}
return ;
}

two strings的更多相关文章

  1. Hacker Rank: Two Strings - thinking in C# 15+ ways

    March 18, 2016 Problem statement: https://www.hackerrank.com/challenges/two-strings/submissions/code ...

  2. StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing the strings?

    StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing t ...

  3. Multiply Strings

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  4. [LeetCode] Add Strings 字符串相加

    Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. ...

  5. [LeetCode] Encode and Decode Strings 加码解码字符串

    Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...

  6. [LeetCode] Group Shifted Strings 群组偏移字符串

    Given a string, we can "shift" each of its letter to its successive letter, for example: & ...

  7. [LeetCode] Isomorphic Strings 同构字符串

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  8. [LeetCode] Multiply Strings 字符串相乘

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  9. 使用strings查看二进制文件中的字符串

    使用strings查看二进制文件中的字符串 今天介绍的这个小工具叫做strings,它实现功能很简单,就是找出文件内容中的可打印字符串.所谓可打印字符串的涵义是,它的组成部分都是可打印字符,并且以nu ...

  10. LeetCode 205 Isomorphic Strings

    Problem: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if ...

随机推荐

  1. MyEclipse常用设置记录

    MyEclipse版本:MyEclipse 2014 Blue版本. 设置内容: 1.内存优化 <MyEclipse_ROOT>/myeclipse-blue.ini文件 主要修改-vma ...

  2. synchronized(2)修饰方法之:普通方法

    synchronized方法 [同一个对象的该方法一次只有一个线程可以访问,该对象的其它同步方法也被阻塞] 方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时, ...

  3. lock to deteck in oracle

    0,5,10 0-23 * * * /home/oracle/utility/blocker/detect_blocker.sh db 120 > /home/oracle/utility/tr ...

  4. 220 Contains Duplicate III 存在重复 III

    给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使 nums [i] 和 nums [j] 的绝对差值最大为 t,并且 i 和 j 之间的绝对差值最大为 k. 详见:https://le ...

  5. 【RSA】在 ASP.NET Core中结合web前端JsEncrypt.JS使用公钥加密,.NET Core使用私钥解密;

    有一个需求,前端web使用的是JsEncrypt把后端给的公钥对密码进行加密,然后后端对其进行解密: 使用的类库如下: 后端使用第三方开源类库Bouncy Castle进行RSA的加解密和生成PEM格 ...

  6. 6月份最新语言排行:Java,Python我更看好谁?

    文章首发于终端研发部,转载,请标明原文链接 今天的主题是:探讨一下6月份语言排行还有我的最新展望! 最近,编程语言排行榜前几天发布更新了,在最新的TIOBE编程语言排行榜中,Java依旧位居第一,但前 ...

  7. 把WebForm移植到.Net MVC中

    最近写项目,想把以前项目中的几个功能页面移植过来(想偷懒一下),在网上查了很多的资料,多数资料都是直接在MVC中添加WebForm,和我的需求不同.在此非常感谢网友“Jason”给予的帮助,终于搞定了 ...

  8. vba,excel,网址提取名字与链接url

    '宏操作 Sub 复制超级链接() '这里控制读取A列的第1到10行,你根据自已的要求修改一下起始和结束行数 ).Hyperlinks.Count > ).Value = Cells(a, ). ...

  9. 以JSONobject形式提交http请求

    总结一下设置图标的三种方式: (1)button属性:主要用于图标大小要求不高,间隔要求也不高的场合. (2)background属性:主要用于能够以较大空间显示图标的场合. (3)drawableL ...

  10. JAVA——不简单的fianl关键字

    protected用来修饰 域,代表域的访问权限是:包权限 或者 不同包,但是是子类 : final 修饰常量只要是该常量代入的计算式,在编译时期,就会被执行计算,以减轻运行时的负担.(只对基本数据类 ...