zoukankan      html  css  js  c++  java
  • poj-2758 Checking the Text

    题意:

    给定一个字符串,要求维护两种操作:
    I:在字符串中插入一个字符;
    Q:询问某两个位置開始的LCP。
    插入操作<=200,字符串长度<=5w,查询操作<=2w;


    题解:

    第一道RKhash题,插入太少让这题变成了傻题;

    注意题中描写叙述的各种恶心的下标讨论;

    插入下标是当前下标。而查询是原下标;

    查询就是二分答案,利用RKhash高速合并的性质搞搞。

    复杂度O(mlogn+100n);

    单组数据。稍微卡常;


    代码:


    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 51000
    #define mod 1000000009ll
    using namespace std;
    typedef unsigned long long ull;
    int p[N],len;
    char str[N],op[10];
    ull hash[N],pow[N];
    void Build(int x)
    {
    	for(int i=x;i<=len;i++)
    		hash[i]=(hash[i-1]*131+str[i])%mod;
    }
    int query(int x,int y)
    {
    	int l=0,r=len-max(x,y)+1;
    	while(l<=r)
    	{
    		int mid=l+r>>1;
    		if((hash[x+mid-1]-hash[x-1]*pow[mid]%mod+mod)%mod==
    		   (hash[y+mid-1]-hash[y-1]*pow[mid]%mod+mod)%mod)
    			l=mid+1;
    		else
    			r=mid-1;
    	}
    	return r;
    }
    int main()
    {
    	int n,m,i,j,k,x,y;
    	pow[0]=1;
    	for(i=1;i<N;i++)
    		pow[i]=pow[i-1]*131%mod;
    	scanf("%s",str+1);
    	n=len=strlen(str+1);
    	scanf("%d",&m);
    	Build(1);
    	for(i=1;i<=n;i++)
    		p[i]=i;
    	for(i=1;i<=m;i++)
    	{
    		scanf("%s",op);
    		if(op[0]=='I')
    		{
    			scanf("%s%d",op,&x);
    			if(x>len)	x=len+1;
    			memcpy(str+x+1,str+x,sizeof(char)*(len-x+1));
    			str[x]=op[0];
    			for(j=n;j>=1;j--)
    			{
    				if(p[j]>=x)
    					p[j]++;
    				else
    					break;
    			}
    			len++;
    			Build(x);
    		}
    		else
    		{
    			scanf("%d%d",&x,&y);
    			printf("%d
    ",query(p[x],p[y]));
    		}
    	}
    	return 0;
    }
    




  • 相关阅读:
    nessus 安装
    firefox SSL_ERROR_RX_RECORD_TOO_LONG burpsuit 报错 解决方案
    Vmware 15 新建虚拟机黑屏
    esp8266 IOT Demo 固件刷写记录
    elk + suricata 实验环境详细安装教程
    停更申明
    求二叉树的深度
    方差
    链表的基本排序
    正态分布及3Sigma原理
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6937801.html
Copyright © 2011-2022 走看看