zoukankan      html  css  js  c++  java
  • bzoj1014

    动态询问LCP,所以我们不好用后缀数组
    考虑使用维护序列问题的splay+hash求LCP
    这里mark一下,hash求LCP常用mo=9875321
    自然溢出的话交上去莫名其妙WA了
    这里树上某节点hash值代表的是这棵子树所代表的序列hash值
    求LCP时,只要二分答案然后提取区间判断hash是否相同即可,实践证明错误率很小
    这里注意要尽量少取模运算,否则会TLE

      1 const mo=9875321;
      2 var son:array[-1..100010,1..2] of longint;
      3     count,fa,hash,a:array[-1..100010] of longint;
      4     d:array[0..100010] of longint;
      5     m,n,root,i,x,y,s:longint;
      6     ch:char;
      7 
      8 procedure update(x:longint);
      9   var l,r:longint;
     10   begin
     11     l:=son[x,1];
     12     r:=son[x,2];
     13     count[x]:=count[l]+count[r]+1;
     14     hash[x]:=hash[l]+a[x]*d[count[l]]+int64(hash[r])*int64(d[count[l]+1]) mod mo;  //计算hash
     15     hash[x]:=hash[x] mod mo;
     16   end;
     17 
     18 function find(k:longint):longint;
     19   var p:longint;
     20   begin
     21     p:=root;
     22     while true do
     23     begin
     24       if count[son[p,1]]+1=k then exit(p);
     25       if count[son[p,1]]+1>k then p:=son[p,1]
     26       else begin
     27         k:=k-count[son[p,1]]-1;
     28         p:=son[p,2];
     29       end;
     30     end;
     31   end;
     32 
     33 procedure rotate(x,w:longint);
     34   var y:longint;
     35   begin
     36     y:=fa[x];
     37     if fa[y]<>-1 then
     38     begin
     39       if son[fa[y],1]=y then son[fa[y],1]:=x
     40       else son[fa[y],2]:=x;
     41     end
     42     else root:=x;
     43     fa[x]:=fa[y];
     44     son[y,3-w]:=son[x,w];
     45     if son[x,w]<>-1 then fa[son[x,w]]:=y;
     46     son[x,w]:=y;
     47     fa[y]:=x;
     48     update(y);
     49   end;
     50 
     51 procedure splay(x,f:longint);
     52   var y:longint;
     53   begin
     54     while fa[x]<>f do
     55     begin
     56       y:=fa[x];
     57       if fa[y]=f then
     58       begin
     59         if son[y,1]=x then rotate(x,2)
     60         else rotate(x,1);
     61       end
     62       else begin
     63         if son[fa[y],1]=y then
     64         begin
     65           if son[y,1]=x then rotate(y,2) else rotate(x,1);
     66           rotate(x,2);
     67         end
     68         else begin
     69           if son[y,1]=x then rotate(x,2) else rotate(y,1);
     70           rotate(x,1);
     71         end;
     72       end;
     73     end;
     74     update(x); //这是学LCT的时候发现的一个优化,每次rotate只要update父节点即可,这样一下子快了2s多
     75   end;
     76 
     77 procedure insert(x,y:longint);
     78   begin
     79     x:=find(x+1);
     80     splay(x,-1);
     81     inc(n);
     82     a[n]:=y;
     83     son[n,2]:=son[x,2];
     84     fa[son[x,2]]:=n;
     85     son[x,2]:=n;
     86     fa[n]:=x;
     87     update(n);
     88     update(x);
     89   end;
     90 
     91 procedure change(x,y:longint);
     92   begin
     93     x:=find(x+1);
     94     splay(x,-1);
     95     a[x]:=y;
     96     update(x);
     97   end;
     98 
     99 function build(l,r:longint):longint;
    100   var m:longint;
    101   begin
    102     m:=(l+r) shr 1;
    103     build:=m;
    104     if l<=m-1 then
    105     begin
    106       son[m,1]:=build(l,m-1);
    107       fa[son[m,1]]:=m;
    108     end;
    109     if m+1<=r then
    110     begin
    111       son[m,2]:=build(m+1,r);
    112       fa[son[m,2]]:=m;
    113     end;
    114     update(m);
    115   end;
    116 
    117 function check(x,l,r:longint):longint;
    118   var y:longint;
    119   begin
    120     y:=find(l+r+1);
    121     splay(x,-1);
    122     splay(y,x);
    123     exit(hash[son[y,1]]);
    124   end;
    125 
    126 function ask(x,y:longint):longint;
    127   var l,r,m,wx,wy:longint;
    128   begin
    129     l:=0;
    130     r:=n-y;
    131     if n-x<r then r:=n-x;
    132     ask:=0;
    133     wx:=find(x);
    134     wy:=find(y);
    135     while l<=r do
    136     begin
    137       m:=(l+r) shr 1;
    138       if check(wx,x,m)=check(wy,y,m) then
    139       begin
    140         l:=m+1;
    141         ask:=m;
    142       end
    143       else r:=m-1;
    144     end;
    145   end;
    146 
    147 begin
    148   fillchar(son,sizeof(son),255);
    149   fillchar(fa,sizeof(fa),255);
    150   read(ch);
    151   while (ch>='a') and (ch<='z') do
    152   begin
    153     inc(n);
    154     a[n]:=ord(ch)-96;
    155     read(ch);
    156   end;
    157   readln(m);
    158   d[0]:=1;
    159   for i:=1 to 100001 do
    160     d[i]:=d[i-1]*29 mod mo;
    161   root:=build(0,n+1);
    162   inc(n);
    163   for i:=1 to m do
    164   begin
    165     read(ch);
    166     if ch='Q' then
    167     begin
    168       readln(x,y);
    169       writeln(ask(x,y));
    170     end
    171     else if ch='I' then
    172     begin
    173       read(x);
    174       read(ch);
    175       readln(ch);
    176       y:=ord(ch)-96;
    177       insert(x,y);
    178     end
    179     else if ch='R' then
    180     begin
    181       read(x);
    182       read(ch);
    183       readln(ch);
    184       y:=ord(ch)-96;
    185       change(x,y);
    186     end;
    187   end;
    188 end.
    View Code
  • 相关阅读:
    使用LAMP创建基于wordpress的个从博客网站
    【solr基础教程之一】Solr相关知识点串讲
    solr源码导入eclipse
    【Nutch2.2.1基础教程之2.2】集成Nutch/Hbase/Solr构建搜索引擎之二:内容分析
    设置secureCRT中vim的字体颜色
    何时使用hadoop fs、hadoop dfs与hdfs dfs命令
    Hadoop常见异常及其解决方案
    Java HashMap遍历的两种方式
    android json 解析简单实例
    Android客户端与数据库交互数据的简单学习
  • 原文地址:https://www.cnblogs.com/phile/p/4473032.html
Copyright © 2011-2022 走看看