先把问题放在后缀数组上考虑

已知两个数组a b,求min(a[i],...,a[j])+(b[i]^b[j])的最大值

套路题

初始每个点都是一个小连通块

把a按从大到小的顺序加入,计算当前加入边作为min的贡献:

每次加入会把两个连通块联通,答案就是两边连通块各出一个数能得到的异或和最大值

我:这不是线性基吗

miaom:mdzz,只能有两个数

我:蛤,好难啊,怎么做啊

miaom:Trie啊

我:哦

没了

  1. #include <bits/stdc++.h>
  2. #define N 500001
  3. #define MAX 18
  4. using namespace std;
  5. int NODE,n;char ch;
  6. int a[N],b[N],c[N*MAX][],size[N],rt[N],lef[N];
  7. pair<int,int> so[N];
  8. int X[N],Y[N],SA[N],Rk[N],Ht[N],v[N];
  9. void GetSA(int a[],int n,int m=)
  10. {
  11. int *x=X,*y=Y,i,p,j;
  12. memset(v,,sizeof v);
  13. for(i=;i<=n;i++)v[x[i]=a[i]]++;
  14. for(i=;i<=m;i++)v[i]+=v[i-];
  15. for(i=n;i>=;i--)SA[v[x[i]]--]=i;
  16. for(i=;i<=n;i<<=,m=p)
  17. {
  18. p=;
  19. memset(v,,sizeof v);
  20. for(j=n-i+;j<=n;j++)y[++p]=j;
  21. for(j=;j<=n;j++)if(SA[j]>i)y[++p]=SA[j]-i;
  22. for(j=;j<=n;j++)v[x[y[j]]]++;
  23. for(j=;j<=m;j++)v[j]+=v[j-];
  24. for(j=n;j>=;j--)SA[v[x[y[j]]]--]=y[j];
  25. swap(x,y);
  26. p=;x[SA[]]=;
  27. for(j=;j<=n;j++)
  28. if(y[SA[j-]]==y[SA[j]]&&y[SA[j-]+i]==y[SA[j]+i]) x[SA[j]]=p;
  29. else x[SA[j]]=++p;
  30. if(p>=n)break;
  31. }
  32. }
  33. void GetHt(int a[],int n)
  34. {
  35. int k=;
  36. for(int i=;i<=n;i++)Rk[SA[i]]=i;
  37. for(int i=;i<=n;i++)
  38. {
  39. if(k)k--;
  40. int j=SA[Rk[i]-];
  41. while(i+k<=n&&j+k<=n&&a[i+k]==a[j+k])k++;
  42. Ht[Rk[i]]=k;
  43. }
  44. }
  45. int build(int x)
  46. {
  47. int rt=++NODE,now=rt;
  48. for(int i=MAX;i>=;i--)
  49. c[now][(x>>i)&]=++NODE,now=NODE;
  50. return rt;
  51. }
  52. int que(int x,int y,int z=)
  53. {
  54. int best=z;
  55. if(c[x][])
  56. if(c[y][]) best=que(c[x][],c[y][],z*+);
  57. else best=que(c[x][],c[y][],z*);
  58. if(c[x][])
  59. if(c[y][]) best=max(best,que(c[x][],c[y][],z*+));
  60. else best=max(best,que(c[x][],c[y][],z*));
  61. return best;
  62. }
  63. void merge(int x,int y)
  64. {
  65. if(c[x][])
  66. if(c[y][]) merge(c[x][],c[y][]);
  67. else c[y][]=c[x][];
  68. if(c[x][])
  69. if(c[y][]) merge(c[x][],c[y][]);
  70. else c[y][]=c[x][];
  71. }
  72. int getfa(int x)
  73. {
  74. if(lef[x]==x) return x;
  75. else return lef[x]=getfa(lef[x]);
  76. }
  77. int main()
  78. {
  79. scanf("%d",&n);
  80. for(ch=getchar();!isalpha(ch);ch=getchar());
  81. for(int i=;i<=n;i++,ch=getchar())
  82. a[i]=ch;
  83. for(int i=;i<=n;i++)
  84. scanf("%d",&b[i]);
  85. GetSA(a,n);
  86. GetHt(a,n);
  87. for(int i=;i<=n;i++)
  88. size[i]=,lef[i]=i,rt[i]=build(b[SA[i]]);
  89. for(int i=;i<=n;i++)
  90. so[i-]=make_pair(n-Ht[i],i);
  91. sort(so+,so+n);
  92. int ret=;
  93. for(int i=;i<n;i++)
  94. {
  95. int x=so[i].second,y=x-,z=n-so[i].first;
  96. x=getfa(x);y=getfa(y);
  97. if(size[x]<size[y]) swap(x,y);
  98. int bes=que(rt[y],rt[x])+z;
  99. if(bes>ret)
  100. ret=bes;
  101. merge(rt[y],rt[x]);
  102. size[x]+=size[y];
  103. lef[y]=x;
  104. }
  105. printf("%d\n",ret);
  106. return ;
  107. }

loj6198谢特 后缀数组+并查集+Trie的更多相关文章

  1. BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集

    http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...

  2. NOI 2015 品酒大会 (后缀数组+并查集)

    题目大意:略 40分暴力还是很好写的,差分再跑个后缀和 和 后缀最大值就行了 一种正解是后缀数组+并查集 但据说还有后缀数组+单调栈的高端操作蒟蒻的我当然不会 后缀数组求出height,然后从大到小排 ...

  3. [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集

    [UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...

  4. Uva 12361 File Retrieval 后缀数组+并查集

    题意:有F个单词,1 <= F <=60 , 长度<=10^4, 每次可以输入一个字符串,所有包含该字串的单词会形成一个集合. 问最多能形成多少个不同的集合.集合不能为空. 分析:用 ...

  5. BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )

    求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ------------------------- ...

  6. 【学术篇】NOI2015 品酒大会 后缀数组+并查集

    省选前大致是刷不了几道题了... 所以就找一些裸一点的题目练练板子算了= = 然而这题一点都不裸, 也并不怎么好写... 于是就浪费了将近一下午的时间... 然而还不是因为后缀数组板子不熟= = 首先 ...

  7. 4199. [NOI2015]品酒大会【后缀数组+并查集】

    Description 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加.在大会的晚餐上,调酒师 ...

  8. 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集

    [BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...

  9. CF 452E. Three strings(后缀数组+并查集)

    传送门 解题思路 感觉这种题都是套路之类的??首先把三个串并成一个,中间插入一些奇怪的字符,然后跑遍\(SA\).考虑按照\(height\)分组计算,就是每个\(height\)只在最高位计算一次, ...

随机推荐

  1. HTML5 拖放:在相册中对照片进行排序

    1. [代码]index.html     <div class="albums">    <div class="album" id=&qu ...

  2. 谷歌新操作系统fuchsia

    开源地址: https://github.com/fuchsia-mirror

  3. 跨线程send message

    今天同事问了一个问题,说在线程中send message 和直接调用是不是一样,他觉得是一样的,但是线程跟踪却发现处理过程是在接收消息队列完成.回家看到博客园上的一番争论才有些明白,这里贴出来,共勉 ...

  4. DLL进一步讲解:extern "C" __declspec(dllexport)

    一.__declspec(dllexport): 将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口. 通常它和extern    "C"   ...

  5. codeforces 569A A. Music(水题)

    题目链接: A. Music time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  6. 网络编程学习笔记-TCP拥塞控制机制

    为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制.最初由V. Jacobson在1988年的论文中提出的TCP的拥塞控制由“慢启动(Slow start)”和“拥塞避免(Congestion ...

  7. 「LOJ#10056」「一本通 2.3 练习 5」The XOR-longest Path (Trie

    #10056. 「一本通 2.3 练习 5」The XOR-longest Path 题目描述 原题来自:POJ 3764 给定一棵 nnn 个点的带权树,求树上最长的异或和路径. 输入格式 第一行一 ...

  8. ssh免密脚本

    #!/bin/sh if [ "$1"x = ""x ]; then echo "usage:/opt/bin/auto-ssh.sh user se ...

  9. HDU1269(有向图缩点模板题)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  10. Python中日志的格式化输出

    import logging logfile = 'e:\\a.txt' # logging.basicConfig(filename=logfile,level=logging.INFO) # lo ...