loj

description

给你一个字符串和一个数组\(w_i\),定义\(\mbox{LCP}(i,j)\)为\(i,j\)两个后缀的最长公共前缀。求\(\max_{i,j}\mbox{LCP}(i,j)+(w_i\ \mbox{xor}\ w_j)\)。

\(n \le 10^5\)

sol

首先,\(\mbox{LCP}(i,j)\)是后缀排序上的一段连续区间的\(\mbox{Height}\)最小值。

那么我们可以枚举这个最小值出现的位置,那么跨越这个位置的所有点对的\(\mbox{LCP}\)就确定了。

接下来我们只要考虑最大化\(w_i\ \mbox{xor}\ w_j\)。

显然可以用可持久化\(\mbox{Tire}\)树实现,复杂度是查询次数\(\times \log n\)的。

算法流程大致是这样的:先找到\(\mbox{Height}\)最小的位置\(p\),计算所有跨越\(p\)的点对的答案。枚举分割点两侧\(size\)较小的一侧,在可持久化\(\mbox{Tire}\)树上查询它和另一侧异或的最大值。接着两侧被完全割裂开,可以分别递归下去处理。

考虑这个东西的时间复杂度。可以发现这就是一个倒着做的启发式合并,所以复杂度就是\(O(n\log^2n)\)。

当然也可以按\(\mbox{Height}\)从大到小启发式合并,复杂度是一样的。

code

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. using namespace std;
  5. int gi(){
  6. int x=0,w=1;char ch=getchar();
  7. while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  8. if (ch=='-') w=0,ch=getchar();
  9. while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
  10. return w?x:-x;
  11. }
  12. const int N = 1e5+5;
  13. struct node{int ch[2],sz;}tr[N*35];
  14. int n,t[N],x[N],y[N],SA[N],Rank[N],Height[N],st[19][N],lg[N],rt[N],tot,w[N],ans;
  15. char s[N];
  16. bool cmp(int i,int j,int k){
  17. return y[i]==y[j]&&y[i+k]==y[j+k];
  18. }
  19. void getSA(){
  20. int m=30;
  21. for (int i=1;i<=n;++i) ++t[x[i]=s[i]-'a'+1];
  22. for (int i=1;i<=m;++i) t[i]+=t[i-1];
  23. for (int i=n;i;--i) SA[t[x[i]]--]=i;
  24. for (int k=1;k<=n;k<<=1){
  25. int p=0;
  26. for (int i=0;i<=m;++i) y[i]=0;
  27. for (int i=n-k+1;i<=n;++i) y[++p]=i;
  28. for (int i=1;i<=n;++i) if (SA[i]>k) y[++p]=SA[i]-k;
  29. for (int i=0;i<=m;++i) t[i]=0;
  30. for (int i=1;i<=n;++i) ++t[x[y[i]]];
  31. for (int i=1;i<=m;++i) t[i]+=t[i-1];
  32. for (int i=n;i;--i) SA[t[x[y[i]]]--]=y[i];
  33. swap(x,y);x[SA[1]]=p=1;
  34. for (int i=2;i<=n;++i) x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
  35. if (p>=n) break;m=p;
  36. }
  37. for (int i=1;i<=n;++i) Rank[SA[i]]=i;
  38. for (int i=1,j=0;i<=n;++i){
  39. if (j) --j;
  40. while (s[i+j]==s[SA[Rank[i]-1]+j]) ++j;
  41. Height[Rank[i]]=j;st[0][i]=i;
  42. }
  43. for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1;
  44. for (int j=1;j<=lg[n];++j)
  45. for (int i=1;i+(1<<j)-1<=n;++i)
  46. if (Height[st[j-1][i]]<Height[st[j-1][i+(1<<j-1)]])
  47. st[j][i]=st[j-1][i];
  48. else st[j][i]=st[j-1][i+(1<<j-1)];
  49. }
  50. int cal(int l,int r){
  51. int k=lg[r-l+1];
  52. if (Height[st[k][l]]<Height[st[k][r-(1<<k)+1]]) return st[k][l];
  53. return st[k][r-(1<<k)+1];
  54. }
  55. void modify(int &x,int p,int dep){
  56. tr[++tot]=tr[x];++tr[x=tot].sz;
  57. if (!~dep) return;
  58. modify(tr[x].ch[(p>>dep)&1],p,dep-1);
  59. }
  60. int query(int x,int y,int p,int dep){
  61. if (!~dep) return 0;
  62. int c=(p>>dep)&1;c^=1;
  63. if (tr[tr[x].ch[c]].sz-tr[tr[y].ch[c]].sz) return query(tr[x].ch[c],tr[y].ch[c],p,dep-1)|(1<<dep);
  64. c^=1;return query(tr[x].ch[c],tr[y].ch[c],p,dep-1);
  65. }
  66. void solve(int l,int r){
  67. if (l==r) return;int mid=cal(l+1,r)-1;
  68. if (mid-l+1<=r-mid){
  69. for (int i=l;i<=mid;++i)
  70. ans=max(ans,Height[mid+1]+query(rt[r],rt[mid],w[SA[i]],18));
  71. }else{
  72. for (int i=mid+1;i<=r;++i)
  73. ans=max(ans,Height[mid+1]+query(rt[mid],rt[l-1],w[SA[i]],18));
  74. }
  75. solve(l,mid);solve(mid+1,r);
  76. }
  77. int main(){
  78. n=gi();scanf("%s",s+1);getSA();
  79. for (int i=1;i<=n;++i) w[i]=gi();
  80. for (int i=1;i<=n;++i) modify(rt[i]=rt[i-1],w[SA[i]],18);
  81. solve(1,n);printf("%d\n",ans);return 0;
  82. }

[LOJ6198]谢特的更多相关文章

  1. loj6198谢特 后缀数组+并查集+Trie

    先把问题放在后缀数组上考虑 已知两个数组a b,求min(a[i],...,a[j])+(b[i]^b[j])的最大值 套路题 初始每个点都是一个小连通块 把a按从大到小的顺序加入,计算当前加入边作为 ...

  2. 【loj6198】谢特

    Portal -->loj6198 Solution ​ (为什么感觉loj上面这几道后缀数组的题..套路都是一样的啊qwq) ​ 同样也是..考虑某个区间\(height[i]\)的最小值的贡 ...

  3. 谢欣伦 - OpenDev原创教程 - 媒体开发库libMedia

    libMedia是一个免费的简单的媒体开发库,其中的接口类与函数大都以小写的x打头,来源于我的姓氏首字母(谢欣伦). 下载 OpenDev for VS2012 libMedia提供四大功能,一是视频 ...

  4. 谢欣伦 - OpenDev原创教程 - 蓝牙设备查找类CxBthRadio & CxBthRadioFind

    这是一个精练的蓝牙设备查找类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxBthRadioFind的使用如下: void CU ...

  5. 谢欣伦 - OpenDev原创教程 - 服务端套接字类CxServerSocket

    这是一个精练的服务端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxServerSocket的使用如下(以某个叫做CSo ...

  6. 谢欣伦 - OpenDev原创教程 - 蓝牙设备查找类CxBthRemoteDeviceFind

    这是一个精练的蓝牙设备查找类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxBthRemoteDeviceFind的使用如下: ...

  7. 谢欣伦 - OpenDev原创教程 - 无连接套接字类CxUdpSocket

    这是一个精练的无连接套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxUdpSocket的使用如下(以某个叫做CSomeC ...

  8. 谢欣伦 - OpenDev原创教程 - 串口类CxSerial

    这是一个精练的串口类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. 串口类CxSerial的使用如下(以某个叫做CSomeClass ...

  9. 谢欣伦 - OpenDev原创教程 - 客户端套接字类CxClientSocket

    这是一个精练的客户端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxClientSocket的使用如下(以某个叫做CSo ...

随机推荐

  1. vw 、vh、vmin 、vmax

    转自:https://blog.csdn.net/romantic_love/article/details/80868909 vw.vh.vmin.vmax是一种视窗单位,也是相对单位. 它相对的不 ...

  2. FromBottomToTop团队项目总结

    FromBottomToTop团队项目总结 项目实现情况 关于塔防游戏项目,已实现下列内容 - 游戏设有菜单,附有简介与游戏玩法 - 游戏设有不同的场景地图可供玩家选择 - 通过智能算法,计算小怪的路 ...

  3. Applet再学习

    ZLYD团队Apllet学习笔记 Applet再学习 Applet是什么? Applet又称为Java小应用程序,是能够嵌入到一个HTML页面中,并且可通过Web浏览器下载和执行的一种Java类 .A ...

  4. QT+qtablewidget自定义表头【合并单元格】

    1.把下列文件放在工程中[已上传到我的文件中] 2.代码 auto *headview = new HHeadViewClass(Qt::Horizontal, ui.tableWidget); he ...

  5. 论文笔记——N2N Learning: Network to Network Compression via Policy Gradient Reinforcement Learning

    论文地址:https://arxiv.org/abs/1709.06030 1. 论文思想 利用强化学习,对网络进行裁剪,从Layer Removal和Layer Shrinkage两个维度进行裁剪. ...

  6. JS判断输入值为正整数

    JS中的test是原来是JS中检测字符串中是否存在的一种模式,JS输入值是否为判断正整数代码: <script type=”text/javascript”> function test( ...

  7. hdu 4745 Two Rabbits 区间DP

    http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意: 有两只兔子Tom Jerry, 他们在一个用石头围城的环形的路上跳, Tom只能顺时针跳,Jerr ...

  8. Codeforces Round #278 (Div. 2) D. Strip 线段树优化dp

    D. Strip time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...

  9. vue之双绑实现

    // html <body> <div id="app"> <input type="text" v-model="nu ...

  10. __all__的作用

    https://blog.csdn.net/orangleliu/article/details/49848413