• BZOJ1014:[JSOI2008]火星人prefix


    Description

    火星人最近研究了一种操作:求一个字串两个后缀的公共前缀。比方说,有这样一个字符串:madamimadam,
    我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字符 m a d a m i m a d a m 现在,
    火星人定义了一个函数LCQ(x, y),表示:该字符串中第x个字符开始的字串,与该字符串中第y个字符开始的字串
    ,两个字串的公共前缀的长度。比方说,LCQ(1, 7) = 5, LCQ(2, 10) = 1, LCQ(4, 7) = 0 在研究LCQ函数的过程
    中,火星人发现了这样的一个关联:如果把该字符串的所有后缀排好序,就可以很快地求出LCQ函数的值;同样,
    如果求出了LCQ函数的值,也可以很快地将该字符串的后缀排好序。 尽管火星人聪明地找到了求取LCQ函数的快速
    算法,但不甘心认输的地球人又给火星人出了个难题:在求取LCQ函数的同时,还可以改变字符串本身。具体地说
    ,可以更改字符串中某一个字符的值,也可以在字符串中的某一个位置插入一个字符。地球人想考验一下,在如此
    复杂的问题中,火星人是否还能够做到很快地求取LCQ函数的值。

    Input

    第一行给出初始的字符串。第二行是一个非负整数M,表示操作的个数。接下来的M行,每行描述一个操作。操
    作有3种,如下所示
    1、询问。语法:Qxy,x,y均为正整数。功能:计算LCQ(x,y)限制:1<=x,y<=当前字符串长度。
    2、修改。语法:Rxd,x是正整数,d是字符。功能:将字符串中第x个数修改为字符d。限制:x不超过当前字
    符串长度。
    3、插入:语法:Ixd,x是非负整数,d是字符。功能:在字符串第x个字符之后插入字符d,如果x=0,则在字
    符串开头插入。限制:x不超过当前字符串长度

    Output

    对于输入文件中每一个询问操作,你都应该输出对应的答案。一个答案一行。

    Sample Input

    madamimadam
    7
    Q 1 7
    Q 4 8
    Q 10 11
    R 3 a
    Q 1 7
    I 10 a
    Q 2 11

    Sample Output

    5
    1
    0
    2
    1

    HINT

    1、所有字符串自始至终都只有小写字母构成。
    2、M<=150,000
    3、字符串长度L自始至终都满足L<=100,000
    4、询问操作的个数不超过10,000个。
    对于第1,2个数据,字符串长度自始至终都不超过1,000
    对于第3,4,5个数据,没有插入操作。

    题解:

    SPLAY!

    维护字符串HASH值,二分答案并验证。

    代码:

    (写的常数有点大,并没有AC。)

      1 var
      2   v,h,p:array[-1..150005]of int64;
      3   size,fa:array[-1..150005]of longint;
      4   c:array[-1..150005,1..2]of longint;
      5   chh:array[1..150005,0..1]of char;
      6   pp:array[1..150005,1..2]of longint;
      7   i,j,k,l,kk,n,m,root:longint;
      8   ch,ch2:char;
      9   s:ansistring;
     10 function min(a,b:longint):longint;
     11 begin
     12   if a>b then exit(b);
     13   exit(a);
     14 end;
     15 procedure up(x:longint);
     16 begin
     17   h[x]:=(h[c[x,1]])and 1073741823;
     18   h[x]:=(h[x]+p[size[c[x,1]]]*v[x])and 1073741823;
     19   h[x]:=(h[x]+h[c[x,2]]*p[size[c[x,1]]+1])and 1073741823;
     20   size[x]:=size[c[x,1]]+1+size[c[x,2]];
     21 end;
     22 function find(x,y:longint):longint;
     23 begin
     24   while true do
     25   begin
     26     if size[c[x,1]]>=y then x:=c[x,1] else
     27     if size[c[x,1]]+1=y then exit(x) else
     28     begin y:=y-size[c[x,1]]-1; x:=c[x,2]; end;
     29   end;
     30 end;
     31 procedure left(x:longint;var xx:longint);
     32 var k,y:longint;
     33 begin
     34   y:=fa[x];
     35   k:=c[x,2]; c[x,2]:=y; fa[k]:=y; c[y,1]:=k;
     36   if y<>xx then
     37   begin if c[fa[y],1]=y then c[fa[y],1]:=x else c[fa[y],2]:=x; end;
     38   fa[x]:=fa[y]; fa[y]:=x;
     39   if y=xx then xx:=x;
     40   up(y); up(x);
     41 end;
     42 procedure right(x:longint;var xx:longint);
     43 var k,y:longint;
     44 begin
     45   y:=fa[x];
     46   k:=c[x,1]; c[x,1]:=y; fa[k]:=y; c[y,2]:=k;
     47   if y<>xx then
     48   begin if c[fa[y],1]=y then c[fa[y],1]:=x else c[fa[y],2]:=x; end;
     49   fa[x]:=fa[y]; fa[y]:=x;
     50   if y=xx then xx:=x;
     51   up(y); up(x);
     52 end;
     53 procedure splay(x:longint;var xx:longint);
     54 var y,z:longint;
     55 begin
     56   while x<>xx do
     57   begin
     58     y:=fa[x]; z:=fa[y];
     59     if y=xx then
     60     begin if c[y,1]=x then left(x,xx)else right(x,xx); end
     61     else if c[y,1]=x then
     62     begin
     63       if c[z,1]=y then left(y,xx)else left(x,xx);
     64     end else
     65     begin
     66       if c[z,1]=y then right(x,xx)else right(y,xx);
     67     end;
     68   end;
     69 end;
     70 function qq(k,l:longint):longint;
     71 var x,y:longint;
     72 begin
     73   x:=find(root,k); y:=find(root,k+l+1);
     74   splay(x,root); splay(y,c[x,2]);
     75   exit(h[c[y,1]]);
     76 end;
     77 function solve(x,y:longint):longint;
     78 var l,r,mid,i:longint;
     79 begin
     80   l:=find(root,x+1); r:=find(root,y+1);
     81   if v[l]<>v[r] then exit(0);
     82   l:=1; r:=min(n-x,n-y);
     83   while l+1<r do
     84   begin
     85     mid:=(l+r)div 2;
     86     if qq(x,mid)=qq(y,mid) then l:=mid else r:=mid-1;
     87   end;
     88   if qq(x,r)=qq(y,r)then exit(r)else exit(l);
     89 end;
     90 procedure bulid(l,r,f:longint);
     91 var mid:longint;
     92 begin
     93   if l>r then exit;
     94   if l=r then
     95   begin
     96     if l=0 then v[l]:=0 else v[l]:=ord(s[l])-ord('a')+1;
     97     h[l]:=v[l]; fa[l]:=f; size[l]:=1;
     98     if l<f then c[f,1]:=l else c[f,2]:=l;
     99     exit;
    100   end;
    101   mid:=(l+r)div 2;
    102   bulid(l,mid-1,mid); bulid(mid+1,r,mid);
    103   if mid=0 then v[mid]:=0 else
    104   v[mid]:=ord(s[mid])-ord('a')+1; fa[mid]:=f; up(mid);
    105   if mid<f then c[f,1]:=mid else c[f,2]:=mid;
    106 end;
    107 begin
    108   p[0]:=1; for i:=1 to 150004 do p[i]:=(p[i-1]*27)and 1073741823;
    109   for i:=-1 to 150004 do begin c[i,1]:=-1; c[i,2]:=-1; end;
    110   readln(s); s:=s+chr(ord('a')-1); n:=length(s);
    111   bulid(0,n,-1); root:=n div 2;
    112   readln(m);
    113   for i:=1 to m do
    114   begin
    115     read(ch); read(ch2); chh[i,0]:=ch;
    116     case ch of
    117       'Q':readln(pp[i,1],pp[i,2]);
    118       'R':begin read(pp[i,1],ch); readln(chh[i,1]); end;
    119       'I':begin read(pp[i,1],ch); readln(chh[i,1]); end;
    120     end;
    121   end;
    122   while(m>0)and(chh[m,0]<>'Q')do dec(m);
    123   for i:=1 to m do
    124   begin
    125     case chh[i,0] of
    126       'Q':begin writeln(solve(pp[i,1],pp[i,2])); end;
    127       'R':begin
    128         l:=find(root,pp[i,1]+1); splay(l,root);
    129         v[l]:=ord(chh[i,1])-ord('a')+1; up(l);
    130       end;
    131       'I':begin
    132         l:=find(root,pp[i,1]+1); splay(l,root);
    133         l:=find(root,pp[i,1]+2); splay(l,c[root,2]);
    134         inc(n); c[l,1]:=n; fa[n]:=l;
    135         v[n]:=ord(chh[i,1])-ord('a')+1; c[n,1]:=-1; c[n,2]:=-1;
    136         up(n); up(fa[n]); up(root);
    137       end;
    138     end;
    139   end;
    140 end.
    View Code
  • 相关阅读:
    Java秒杀系统实战系列~整合RabbitMQ实现消息异步发送
    Java秒杀系统实战系列~分布式唯一ID生成订单编号
    Java秒杀系统实战系列~商品秒杀代码实战
    Java秒杀系统实战系列~整合Shiro实现用户登录认证
    Java秒杀系统实战系列~待秒杀商品列表与详情功能开发
    Java秒杀系统实战系列~整体业务流程介绍与数据库设计
    Java秒杀系统实战系列~构建SpringBoot多模块项目
    重磅发布- Java秒杀系统的设计与实战视频教程(SpringBoot版)
    ct
    mysql 分区表
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6294768.html
Copyright © 2020-2023  润新知