题目

【题目描述】

由于你成功地在 $ ext{1 s} $ 内算出了上一题的答案,英雄们很高兴并邀请你加入了他们的游戏。然而进入游戏之后你才发现,英雄们打的游戏和你想象的并不一样……

英雄们打的游戏是这样的:首先系统会产生(**注意不一定是随机产生**)一个字符串,然后每个英雄就会开始根据自己分到的任务计算这个字符串的某些特征,谁先算出自己的答案谁就是胜者。

由于打游戏的英雄比较多,因此英雄们分到的任务也就可能很奇怪。比如你分到的这个任务就是这样:

定义这个字符串以第 $ i $ 个字符开头的后缀为后缀 $ i $ (编号从 $ 1 $ 开始),每个后缀 $ i $ 都有一个权值 $ w_i $ ,同时定义两个后缀 $ i,j $ ($ i

e j $) 的贡献为它们的最长公共前缀长度加上它们权值的异或和,也就是 $ mathrm{LCP}(i,j)+(w_i mathbin{ext{xor}} w_j) $ 。而你的任务就是,求出这个字符串的所有后缀两两之间贡献的最大值。

【输入格式】

第一行一个正整数 $ n $,表示字符串的长度。

第二行一个仅包含小写英文字母的字符串,即系统产生的字符串。

第三行 $ n $ 个非负整数 $ w_i $,分别表示后缀 $ 1 $ ~ $ n $ 的权值。

【输出格式】

一行一个整数表示答案。

【样例输入】

7

acbabac

0 1 5 6 4 2 3

【样例输出】

7

【样例解释】

后缀 $ 1 $ 和后缀 $ 4 $ 的贡献是 $ 1+(0;ext{xor};6)=7 $ ,不难验证它们的贡献确实是所有可能的贡献中最大的。

【数据范围与提示】

对于 $ 30\% $ 的数据,$ nle 5imes 10^3 $;

对于另 $ 30\% $ 的数据,保证字符串是随机生成的;

对于另 $ 10\% $ 的数据,$ w_i=0 $;

对于另 $ 10\% $ 的数据,$ w_ile 1 $;

对于 $ 100\% $ 的数据,$ nle 10^5 $,$ w_i< n $ 。

题解

求任意两个后缀的 LCP 很容易想到后缀数组

记排序后的两个相邻后缀 $ i-1,i $ 的 LCP 为 $ height[i] $

那么任意的两个后缀 $ i,j $ 的 LCP 为 $ min_{k=i}^{j}height[k] $

至于求 $W$ 的异或值考虑在 tire 树上贪心

当 $ height[i] $ 为 $[l,r] $ 的最小值时才会对该区间有影响,那么考虑如何用 $ height[i] $ 来更新答案

将 $ height[i] $ 从大到小排序后,合并 $ P_i $ 和 $ P_{i-1} $ 属于的两个区间 $ [L_{P_i},R_{p_i}] $ 和 $ [L_{P_{i-1}},R_{P_{i-1}}] $,此时保证 $ height[i] $ 为两个区间中的最小值(因为比 $ i $ 大的已经合并了)

然后在 tire 树上启发式合并两个区间即可,贪心选取答案

时间效率:$ O(n log n+n log^2n)$

至于 SA 的排序可以用倍增法或者二分哈希都可以(也就多一个 $ log $,反正启发式合并也要 $ log^2 $)

为什么我一点都没有感觉到套路,可能是题写太少了

代码

1 #include

2 #define LL long long

3 #define _(d) while(d(isdigit(ch=getchar())))

4 using namespacestd;5 intR(){6 int x;bool f=1;char ch;_(!)if(ch==‘-‘)f=0;x=ch^48;7 _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}8 const int N=2e5+5;9 intn,m,w[N],p[N],ht[N],rak[N],tp[N],sa[N],tax[N],ans;10 charch[N];11 voidQsort(){12 for(int i=0;i<=m;i++)tax[i]=0;13 for(int i=1;i<=n;i++)tax[rak[tp[i]]]++;14 for(int i=1;i<=m;i++)tax[i]+=tax[i-1];15 for(int i=n;i>=0;i--)sa[tax[rak[tp[i]]]--]=tp[i];16 }17 voidSA(){18 m=26,Qsort();19 for(int l=1,p=0;l<=n;l<<=1){20 for(int i=n-l+1;i<=n;i++)tp[++p]=i;21 for(int i=1;i<=n;i++)if(sa[i]>l)tp[++p]=sa[i]-l;22 Qsort(),swap(rak,tp);23 rak[sa[1]]=p=1;24 for(int i=2;i<=n;i++)25 rak[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+l]==tp[sa[i]+l])?p:++p;26 if(p>n)break;27 m=p+1,p=0;28 }29 int k=0;30 for(int i=1,j;i<=n;i++){31 j=sa[rak[i]-1];32 if(k)k--;33 while(ch[j+k]==ch[i+k])k++;34 ht[rak[i]]=k;35 }36 }37 bool cmp(int a,int b){return ht[a]>ht[b];}38 int li[N],ri[N],fa[N],rt[N],tot,tr[N*50][2];39 int query(int k,int dep,intval){40 if(!~dep)return 0;41 if(tr[k][((val>>dep)&1)^1])42 return (1<>dep)&1)^1],dep-1,val);43 else return query(tr[k][(val>>dep)&1],dep-1,val);44 }45 void insert(int &k,int dep,intval){46 if(!k)k=++tot;47 if(~dep)insert(tr[k][(val>>dep)&1],dep-1,val);48 }49 int merge(int x,inty){50 int res=0;51 if(ri[x]-li[x]

View Code

java tire树_谢特——后缀数组+tire 树(示例代码)相关推荐

  1. HDU - 6704 K-th occurrence (后缀数组+主席树)

    题目链接 题意 QQQ次询问,每次询问求SSS的子串出现KKK次的位置 思路 刚开始想的是AC自动机,但是建自动机会超时,后来学长想到后缀数组+主席树的做法Orz...Orz...Orz... 出现K ...

  2. HDU 6194 String String String (后缀数组+线段树, 2017 ACM/ICPC Asia Regional Shenyang Online)

    Problem 求字符串 S 中严格出现 k 次的子串个数 k≥1k\ge 1 |S|≤105|S|\le 10^5 ∑|S|≤2×106\sum |S| \le 2\times 10^6 Idea ...

  3. BZOJ3473:字符串(后缀数组,主席树,二分,ST表)

    Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...

  4. CF-547E(Mike and Friends)后缀数组+线段树 AC自动机+DFS序+树状数组

    题目链接 题意 NNN个串,每次询问区间[L,R][L,R][L,R]中有多少子串SiS_iSi​ 思路 把NNN个串合成一个长字符串,对这个长字符串求后缀数组,包含SiS_iSi​的子串的heigh ...

  5. [HEOI2016/TJOI2016]字符串 (后缀数组+主席树+二分)

    description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为 n 的字符串 s,和 m 个问题.佳媛姐姐必须正确回答这 m 个问 ...

  6. 洛谷P4094 [HEOI2016/TJOI2016]字符串【后缀数组+主席树+st表】

    时空限制 2000ms / 256MB 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须正确 ...

  7. bzoj2754:[SCOI2012]喵星球上的点名 (后缀数组+离线+树状数组)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2754 题目分析:最近两个星期都在做数论题,感觉有些无聊.昨天忽然间想起省赛前还有一个这题 ...

  8. java args用法_Java中args参数数组的用法说明代码

    本篇文章小编给大家分享一下Java中args参数数组的用法说明代码,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. main方法args参数用于接收用户 ...

  9. java开发保险案例_Java实现双保险线程的示例代码

    双保险线程,每次启动2个相同的线程,互相检测,避免线程死锁造成影响. 两个线程都运行,但只有一个线程执行业务,但都会检测对方的时间戳 如果时间戳超过休眠时间3倍没有更新的话,则重新启动对方线程. 例子 ...

  10. java图片转换pdf_Java实现图片转换PDF文件的示例代码

    最近因为一些事情,需要将一张简单的图片转换为PDF的文件格式,在网上找了一些工具,但是这些工具不是需要注册账号,就是需要下载软件. 而对于只是转换一张图片的情况下,这些操作显然是非常繁琐的,所以作者就 ...

最新文章

  1. 区块链之比特币的潜在激励
  2. 打造线下版元宇宙!机器人VR助力远程做核酸,登上Science子刊
  3. 自然辩证法的当代价值
  4. 2017 全球超大规模数据中心已超过 390 个,中国仅占 8%
  5. 构造函数调用默认构造函数_显式无参数构造函数与默认构造函数
  6. Transparent 之 TransparentBlt
  7. Linq连接查询之左连接、右连接、内连接、全连接、交叉连接、Union合并、Concat连接、Intersect相交、Except与非查询...
  8. 【转载】 C#中decimal.TryParse方法和decimal.Parse方法的异同之处
  9. 【特征提取】基于matlab倒谱距离端点检测【含Matlab源码 1767期】
  10. 计算机组装与维修第3版,计算机组装与维护(第3版)
  11. jq匹配偶数行_jQuery 偶数选择器(:even )的介绍
  12. 部署项目启动提示找不到locahost:8080.....地址问题
  13. grub引导项修复详解_grub2修复引导 · LINCHUAN的小站
  14. dns配置异常怎么修复_dns配置异常不能上网如何修复
  15. HTML配色工具!在线配色工具
  16. Hexo-Fluid主题添加音乐页面
  17. OA系统十九:请假申请五:【请假申请】这个内嵌页面的前台文件;设置【点击左侧菜单栏的“请假申请”后】在首页的“功能区”显示【请假功能】这个内嵌页面;
  18. Android开发者指南
  19. Pippo已经不能只用超级来形容了
  20. runtime-compiler和runtime-only的区别

热门文章

  1. Win10系统中耳机插入前后面板均没有声音
  2. 图文并茂:超可爱的12星座猫
  3. unimrcpserver的MRCP消息处理
  4. 数据库服务器如何备份详细教程!
  5. 禁止chrome更新呢
  6. 定时任务的多种实现——xxl-job
  7. 基于Python的招聘网站招聘信息分析
  8. 神州信息与瀚华金控签署战略协议 共推数字普惠金融
  9. 对前端页面的边框设置
  10. 爆款AR游戏如何打造?网易杨鹏以《悠梦》为例详解前沿技术