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

已知两个数组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][2],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=256)
 10 {
 11     int *x=X,*y=Y,i,p,j;
 12     memset(v,0,sizeof v);
 13     for(i=1;i<=n;i++)v[x[i]=a[i]]++;
 14     for(i=1;i<=m;i++)v[i]+=v[i-1];
 15     for(i=n;i>=1;i--)SA[v[x[i]]--]=i;
 16     for(i=1;i<=n;i<<=1,m=p)
 17     {
 18         p=0;
 19         memset(v,0,sizeof v);
 20         for(j=n-i+1;j<=n;j++)y[++p]=j;
 21         for(j=1;j<=n;j++)if(SA[j]>i)y[++p]=SA[j]-i;
 22         for(j=1;j<=n;j++)v[x[y[j]]]++;
 23         for(j=1;j<=m;j++)v[j]+=v[j-1];
 24         for(j=n;j>=1;j--)SA[v[x[y[j]]]--]=y[j];
 25         swap(x,y);
 26         p=1;x[SA[1]]=1;
 27         for(j=2;j<=n;j++)
 28             if(y[SA[j-1]]==y[SA[j]]&&y[SA[j-1]+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=0;
 36     for(int i=1;i<=n;i++)Rk[SA[i]]=i;
 37     for(int i=1;i<=n;i++)
 38     {
 39         if(k)k--;
 40         int j=SA[Rk[i]-1];
 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>=0;i--)
 49         c[now][(x>>i)&1]=++NODE,now=NODE;
 50     return rt;
 51 }
 52 int que(int x,int y,int z=0)
 53 {
 54     int best=z;
 55     if(c[x][0])
 56          if(c[y][1]) best=que(c[x][0],c[y][1],z*2+1);
 57          else best=que(c[x][0],c[y][0],z*2);
 58     if(c[x][1])
 59         if(c[y][0]) best=max(best,que(c[x][1],c[y][0],z*2+1));
 60         else best=max(best,que(c[x][1],c[y][1],z*2));
 61     return best;
 62 }
 63 void merge(int x,int y)
 64 {
 65     if(c[x][0])
 66          if(c[y][0]) merge(c[x][0],c[y][0]);
 67          else c[y][0]=c[x][0];
 68     if(c[x][1])
 69         if(c[y][1]) merge(c[x][1],c[y][1]);
 70         else c[y][1]=c[x][1];
 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=1;i<=n;i++,ch=getchar())
 82         a[i]=ch;
 83     for(int i=1;i<=n;i++)
 84         scanf("%d",&b[i]);
 85     GetSA(a,n);
 86     GetHt(a,n);
 87     for(int i=1;i<=n;i++)
 88         size[i]=1,lef[i]=i,rt[i]=build(b[SA[i]]);
 89     for(int i=2;i<=n;i++)
 90         so[i-1]=make_pair(n-Ht[i],i);
 91     sort(so+1,so+n);
 92     int ret=0;
 93     for(int i=1;i<n;i++)
 94     {
 95         int x=so[i].second,y=x-1,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 0;
107 } 

转载于:https://www.cnblogs.com/wanglichao/p/7272870.html

loj6198谢特 后缀数组+并查集+Trie相关推荐

  1. 【BZOJ4199】品酒大会,后缀数组+并查集维护

    Time:2016.05.23 Author:xiaoyimi 转载注明出处谢谢 传送门 题面及样例 思路: 求lcp相关问题上有类似于差异的地方,但不完全是,"差异"所求的是lc ...

  2. P2178 后缀数组 + 并查集

    题目传送门 题意: 调酒师  调制了  杯鸡尾酒.这  杯鸡尾酒排成一行,其中第  杯酒被贴上了一个标签  ,每杯酒有一个美味值,每个标签都是  个小写英文字母之一,把这些酒想象为一个字符串  .两个 ...

  3. 花神游历各国 题解(小清新线段树/树状数组+并查集)

    题面 众所周知,这是一道小清新线段树 然而可以用树状数组水过去且跑得飞快 看到区间开方第一反应肯定是线段树懒标记区间修改之类的,但是这个东西似乎确凿不可维护 所以考虑暴力循环单点修改->T飞 于 ...

  4. hdu 6200 mustedge mustedge mustedge(dfs序+树状数组+并查集)

    题目链接:hdu 6200 mustedge mustedge mustedge 题意: 一开始给你一个有n个节点m条无向边的图,现在定义mustedge为u->v的路径上必须经过的边. 现在有 ...

  5. POJ-2985(树状数组 + 并查集 + 二分)

    题目:http://poj.org/problem?id=2985 这题考察了两个点呢,组合并用到了并查集,求第K大的数用到了树状数组,刚开始WA了几次,发现是在组合并之后仅仅update(*, -1 ...

  6. sa后缀数组使用合集,包括height数组求LPC和LCS,ST表,单调队列优化。

    P5546 [POI2000]公共串 所有串合在一起,每两个串放不同的字符,求一遍后缀数组,然后利用height数组求LCS即可. #include<iostream> #include& ...

  7. [蓝桥杯][2019年第十届真题]修改数组(并查集)

    题目描述 给定一个长度为 N 的数组 A = [A1, A2, · · · AN ],数组中有可能有重复出现 的整数. 现在小明要按以下方法将其修改为没有重复整数的数组.小明会依次修改 A2,A3,· ...

  8. [蓝桥杯2019初赛]修改数组-并查集

    代码如下: #include <iostream> using namespace std; const int N = 1000010; int a[N];int find(int x) ...

  9. 算法:程序设计之并查集

    前言 之前一直都是听说并查集,感觉是一个神乎其技,狂拽酷炫.却没有想过在自己学习并查集之前,自已在解决问题的时候也能够想到一个和并查集异曲同工的方法.这个还是很愉快的. 版权说明 著作权归作者所有. ...

  10. 【NOI2015】品酒大会【后缀数组】【并查集】

    传送门 传送门 题意:给一个长度为NNN的字符串和一个长度为NNN的序列AAA,对于所有的k∈[0,N−1]k \in [0,N-1]k∈[0,N−1],求选出两个数i,ji,ji,j满足lcp(su ...

最新文章

  1. 大失所望:第一次去苹果店“享受”维修服务的经历
  2. 斯坦福2019秋季课程CS224W
  3. [Database] 数据库范式理论
  4. 第一篇文章,,测试效果,
  5. 服务器环境~某个页面无法访问的处理
  6. Invalid Gradle JDK configuration found_带你了解Gradle编译速度是如何提升70%的
  7. [翻译]2005年软件业界推出新产品非官方计划
  8. vue获取输入框得内容_React入坑(四):获取输入框内的内容
  9. 中国居住服务业数字化发展报告
  10. jQuery 历史版本
  11. Jquery,Ready函数.
  12. 【Caffe安装】Caffe安装(无GPU)--wanglei
  13. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_4_字节输出流写入数据到文件...
  14. Bat批处理命令大全
  15. 分布式技术核心(上)-ZookeeperDubbo
  16. 内存刺客在哪儿?! 微信11年膨胀575倍,只有微信被发现了
  17. LoadRunner性能测试实战视频教程下载
  18. mssql 2000 备份计划
  19. SpringCloud分布式开发理解
  20. Mysql 当前月每天累计统计,Mysql 本月第一天

热门文章

  1. c语言void delay是什么意思,delay什么意思
  2. [编程题]雀魂启动!(java实现)
  3. 谁在「连接」制造业?
  4. 小网站云服务器配置推荐,小网站云服务器配置推荐
  5. SpringCloud 微服务网关Gateway常用限流算法以及简单实现
  6. 小草 李白 《菩萨蛮》
  7. Ubuntu快速安装或更新chrome
  8. chm文件转换成单个html
  9. dfuse 的 GraphQL 端点现在提供经过 ABI 解码的数据库行为信息
  10. 解决Mybatis报错问题:Type interface com.tjcu.dao.UserDao is not known to the MapperRegistry.