two strings

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+10,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=0;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[20][maxn],p[maxn];
int ask(int l,int r)
{
    int x=p[r-l+1];
    return min(mi[x][l],mi[x][r-(1<<x)+1]);
}
void solve(int n,int m)
{
    for (int i = 0; i < m; i ++) cntA[i] = 0;
    for (int i = 1; i <= n; i ++) cntA[ch[i]] ++;
    for (int i = 1; i < m; i ++) cntA[i] += cntA[i - 1];
    for (int i = n; i; i --) sa[cntA[ch[i]] --] = i;
    lev[sa[1]] = 1;
    for (int i = 2; i <= n; i ++)
    {
        lev[sa[i]] = lev[sa[i - 1]];
        if (ch[sa[i]] != ch[sa[i - 1]]) lev[sa[i]] ++;
    }
    for (int l = 1; lev[sa[n]] < n; l <<= 1)
    {
        memset(cntA,0,sizeof(cntA[0])*(n+1));
        memset(cntB,0,sizeof(cntB[0])*(n+1));
        for (int i = 1; i <= n; i ++)
        {
            cntA[A[i] = lev[i]] ++;
            cntB[B[i] = (i + l <= n) ? lev[i + l] : 0] ++;
        }
        for (int i = 1; i <= n; i ++) cntB[i] += cntB[i - 1];
        for (int i = n; i; i --) tsa[cntB[B[i]] --] = i;
        for (int i = 1; i <= n; i ++) cntA[i] += cntA[i - 1];
        for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i];
        lev[sa[1]] = 1;
        for (int i = 2; i <= n; i ++)
        {
            lev[sa[i]] = lev[sa[i - 1]];
            if (A[sa[i]] != A[sa[i - 1]] || B[sa[i]] != B[sa[i - 1]]) lev[sa[i]] ++;
        }
    }
    for (int i = 1, j = 0; i <= n; i ++)
    {
        if (j) j --;
        while (ch[i + j] == ch[sa[lev[i] - 1] + j]) j ++;
        height[lev[i]] = j;
    }
}
int main() {
    int i,j;
    //freopen("in.txt","r",stdin);
    tot=0;
    int ha=-1,ta=-1,hb=-1,tb=-1;
    scanf("%s",ch+1);
    for(i=1;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+1);
    for(i=1;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=1;i<=m;i++)
    {
        int op;
        char str[2];
        scanf("%d",&op);
        q[i].op=op;
        if(op==5)continue;
        scanf("%s",str);
        e[tot].x=str[0]-‘a‘;
        e[tot].id=i;
        if(op==1)
        {
            e[tot].nt=ha;
            ha=tot;
        }
        else if(op==2)
        {
            e[ta].nt=tot;
            ta=tot;
        }
        else if(op==3)
        {
            e[tot].nt=hb;
            hb=tot;
        }
        else if(op==4)
        {
            e[tb].nt=tot;
            tb=tot;
        }
        tot++;
    }
    tot=0;
    int sx,sy,ex,ey;
    sx=sy=-1;
    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]=26;
    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,27);
    for(i=2;i<=tot;i++)p[i]=1+p[i>>1];
    for(i=0;1<<i<=tot;i++)
    {
        for(j=1;j+(1<<i)<=tot;j++)
        {
            if(!i)mi[i][j]=height[j];
            else mi[i][j]=min(mi[i-1][j],mi[i-1][j+(1<<(i-1))]);
        }
    }
    //cout<<sx<<" "<<ex<<" "<<sy<<" "<<ey<<endl;
    for(i=sx;i+ey-sy<=ex;i++)add(lev[i],1);
    for(i=1;i<=m;i++)
    {
        int op=q[i].op;
        if(op==1)
        {
            sx--;
            if(sx+ey-sy<=ex)add(lev[sx],1);
        }
        else if(op==2)
        {
            ex++;
            if(sx+ey-sy<=ex)add(lev[ex-ey+sy],1);
        }
        else if(op==3)
        {
            sy--;
            if(ex-ey+sy+1>=sx)add(lev[ex-ey+sy+1],-1);
        }
        else if(op==4)
        {
            ey++;
            if(ex-ey+sy+1>=sx)add(lev[ex-ey+sy+1],-1);
        }
        else
        {
            int pos=lev[sy],len=ey-sy+1;
            int l=1,r=pos-1,pl=pos,pr=pos;
            while(l<=r)
            {
                int mid=l+r>>1;
                if(ask(mid+1,pos)>=len)pl=mid,r=mid-1;
                else l=mid+1;
            }
            l=pos+1,r=tot;
            while(l<=r)
            {
                int mid=l+r>>1;
                if(ask(pos+1,mid)>=len)pr=mid,l=mid+1;
                else r=mid-1;
            }
            printf("%d\n",get(pr)-get(pl-1));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/dyzll/p/9594974.html

时间: 2024-10-10 19:03:00

two strings的相关文章

43. Multiply Strings

1. 问题描述 Given two numbers represented as strings, return multiplication of the numbers as a string.Note:The numbers can be arbitrarily large and are non-negative.Converting the input string to integer is NOT allowed.You should NOT use internal librar

Multiply Strings

package cn.edu.xidian.sselab;/** * title:Multiply Strings * content: * Given two numbers represented as strings, return multiplication of the numbers as a string. * Note: The numbers can be arbitrarily large and are non-negative. * 读已知条件可以,两个String转换

leetcode笔记:Isomorphic Strings

一.题目描述 Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order of chara

LeetCode:Isomorphic Strings

1.题目名称 Isomorphic Strings(同构的字符串) 2.题目地址 https://leetcode.com/problems/isomorphic-strings/ 3.题目内容 英文: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurre

poj 2406 Power Strings KMP

Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative inte

go语言学习 strings常用函数

strings包中的函数用法 参考链接http://studygolang.com/articles/88 1.strings.replace() 函数原型 func Replace(str1, old, str2, n int) string //old是str1中的字符串,用str2替换str1中的old,一共替换n个.如果n<0,则全部替换 fmt.Println(strings.Replace("tet tet tet", "e", "es&

strings用法小记

By francis_hao    Feb 14,2017 打印文件中可打印字符,每个序列至少四(可配置)个字符长.主要用于显示非文本文件 概述 选项解释 -a --all - 扫描整个文件,不管那些段是否被加载或初始化,一般此项是默认的,除非程序被配置成-d的模式 -d --data 只打印初始化过或加载过的部分,此项可以减少一些垃圾数据. -f --print-file-name 在打印字符之前打印文件名 -min-len -n min-len --bytes=min-len 指定打印的最短

Power Strings(KMP)

Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 45008   Accepted: 18794 Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "

[shiro] Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.

访问某页面时,出现了这个异常: java.lang.IllegalArgumentException: Wildcard string cannot be null or empty. Make sure permission strings are properly formatted. at org.apache.shiro.authz.permission.WildcardPermission.setParts(WildcardPermission.java:154) at org.apa

LeetCode-Isomorphic Strings

Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order of characters.