Codechef January Challenge 2018 - Killjee and k-th letter

题意:
给出一个的串 s,将 s 所有子串按照字典序排列好相接起来形成一个新串q次询问,每一次询问问新串中的第 k 个字符是什么,强制在线。

$|s|,q \le 2*10^{5} $

 

 

跟所有子串有关,那肯定要么是后缀自动机,要么是后缀树。

考虑后缀自动机。即使后缀自动机单次询问可以做到线性,在这题也无施展之地。鉴于他DAWG的性质,没有什么东西可以维护。

然而后缀树就不一样了,[TJOI2015] 弦论有一种O(n+logn)的做法,可以参考Mangoyang的博客。

实际上考虑 parent 可以进一步优化算法的复杂度,考虑原先的 parent 树一个节点代表的多个串都是最长的串的一个后缀,是一棵类似于前缀树的结构,这样不能适用于一些字典序上优美的性质。不妨将串反序插入到sam 中,这样每一个点能代表的多个串都是最长的串的前缀,这些串从长到短在字典序上一定是有序的。扩展到整棵树上,根据 minlen(u)=len(fa(u))+1 ,每个点代表的字符串都比其祖先代表的字符串的字典序大。于是可以计算出每一棵子树代表了多少串,在 dfn 序上二分答案即可

类似的,也可以计算出后缀树每一颗子树代表的串的总长,并且通过构造可以使后缀树上字符串的字典序与 dfn 序同时有序。这样找到了后缀树上的一个节点后,考虑一个子串其所代表的串长度在 [len(fa(u))+1,len(u)] 上连续,在这个节点上继续二分答案就可以找到第k个字符所在的子串及它的长度,再计算一下就能知道第k个字符在s中的位置了。时间复杂度O(n+qlogn)

 

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 #define ll long long
 4 int const N=200000+10;  
 5 struct node{
 6     int len,fa,ch[26];  
 7 }a[N<<1];  
 8 int tot,ls,w[N<<1],num[N],sa[N<<1],cnt,pos[N<<1],son[N<<1][26];  
 9 ll sum[N<<1],l[N<<1],sz[N<<1],qs[N<<1];  
10 char s[N];   
11 void add(int c,int id){
12     int p=ls;  
13     int np=ls=++tot;  
14     a[np].len=a[p].len+1;  
15     w[tot]=id;  
16     sz[tot]=1;  
17     for(;p&&!a[p].ch[c];p=a[p].fa) a[p].ch[c]=np; 
18     if(!p) a[np].fa=1;  
19     else {
20         int q=a[p].ch[c];  
21         if(a[q].len==a[p].len+1) a[np].fa=q;  
22         else { 
23             int nq=++tot;  
24             a[nq]=a[q];  
25             a[nq].len=a[p].len+1;  
26             a[q].fa=a[np].fa=nq;  
27             for(;p&&a[p].ch[c]==q;p=a[p].fa)   
28                 a[p].ch[c]=nq;  
29         } 
30     } 
31 }  
32 void dfs(int x){ 
33     if(!x ) return ;  
34     pos[++cnt]=x;    
35     for(int i=0;i<26;i++)  
36         dfs(son[x][i]);  
37 }  
38 int main(){
39     scanf("%s",s);  
40     int len=strlen(s); 
41     tot=ls=1;    
42     for(int i=len-1;i>=0;i--) 
43         add(s[i]-'a',i+1);  
44     for(int i=2;i<=tot;i++)     
45         sum[i]=1;    
46     for(int i=1;i<=tot;i++) num[a[i].len]++;  
47     for(int i=1;i<=len;i++) num[i]+=num[i-1];  
48     for(int i=1;i<=tot;i++) sa[num[a[i].len]--]=i; 
49     for(int i=tot;i>=1;i--){
50         int x=sa[i];
51         int f=a[x].fa;    
52         sz[f]+=sz[x]; 
53         w[f]=w[f    ]? w[f]:w[x];    
54     }  
55     for(int i=2;i<=tot;i++){
56         int x=a[i].fa; 
57         int y=s[w[i]+a[a[i].fa].len-1]-'a';  
58         son[x][y]=i;
59     }
60     dfs(1);    
61     for(int i=2;i<=tot;i++) { 
62         int t=pos[i];  
63         ll x=a[a[t].fa].len+1;  
64         ll y=a[t].len;  
65         ll tmp=sz[t]*(x+y)*(y-x+1)/2;  
66         qs[i]=qs[i-1]+tmp; 
67     }   
68 
69     int q;  
70     scanf("%d",&q);  
71     ll g=0;  
72     while (q--){
73         ll p,m;      
74         scanf("%lld%lld",&p,&m);    
75         ll k=p*g % m +1;           
76         int t=lower_bound(qs+1,qs+tot+1,k)-qs;      
77         k-=qs[t-1];  
78         t=pos[t];
79         ll x=a[a[t].fa].len+1;
80         ll y=a[t].len;  
81         ll tmp=sz[t]*(x+y)*(y-x+1)/2;   
82         ll l=x,r=y;  
83         while (l<r){
84             ll mid=(l+r)/2;  
85             tmp=sz[t]*(x+mid)*(mid-x+1)/2;  
86             if(tmp>=k) r=mid; 
87             else l=mid+1; 
88         }  
89         k-=sz[t]*(x+r-1)*(r-x)/2;    
90         k=(k-1) % r+1;  
91         int c=w[t]+k-2;       
92         printf("%c\n",s[c]);    
93         g+=s[c];  
94     }
95     return 0; 
96 }     
View Code

 

转载于:https://www.cnblogs.com/ZJXXCN/p/11054391.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/263736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AppFabric Caching Admin Tool

最近试用了一下MS的AppFabric的分布是缓存&#xff08;Velocity&#xff09;&#xff0c;发现了一个不错的可视化配置工具挺有用&#xff0c;先介绍给大家&#xff0c;后续再详细介绍。 http://mdcadmintool.codeplex.com/ Project Description The AppFabric Caching Admin To…

剑指offer——最小的K个数和数组中第K大的元素

解题思路&#xff1a; 乘着做这个题&#xff0c;顺便复习下堆排序。 先说堆排序是一个什么东西&#xff1a;https://blog.csdn.net/u013384984/article/details/79496052 大顶堆升序&#xff0c;小顶堆降序。 随便定义的一个堆。 第一步&#xff1a; 此时我们从最后一个非叶子结…

GIS二次开发之初探

最近一段时间在学习GIS的二次开发&#xff0c;作为新手&#xff0c;最好的方法就是泡论坛&#xff0c;看原码&#xff0c;当然涉及到地理方面的专业知识&#xff0c;不可能说一两天就可以弄懂&#xff0c;只有在学习编程的过程中慢慢的去体会一些地理专业上面的知识。 就几天的…

linux传奇源码,游戏源码 屠龙传奇H5 鲲乃异兽 全套源码+教程

一、游戏的要求系统要求系统要求liunx6.9系统 因为游戏是java对服务器配置要求比较高如果您的资金够宽裕可以选择直接购买 liunx6.9系统 8核16G 240G/320G硬盘 10兆以上宽带的服务器 这样可以直接保证游戏的稳定性如果不想出那么多钱 可以一步一步来开新区用4核4G 1…

如何量化考核软件开发人员绩效

为什么80%的码农都做不了架构师&#xff1f;>>> 1、首先有技术积累的前提下&#xff0c;能比较正确的估量项目成本和项目组生产率 2、设立项目组短期目标、中期、长期目标&#xff08;这个因项目具体情况而已&#xff0c;有些项目都是很小的&#xff0c;甚至2个星期…

linux创建自定义组件qt,关于QT自定义控件

Linux中I/O设备分为两类&#xff1a;块设备和字符设备。两种设备本身没有严格限制&#xff0c;但是&#xff0c;基于不同的功能进行了分类。用户自定义的控件可以通过继承现有的 Qt 控件实现&#xff0c;也可以直接从 QWidget 继承。QT中的label控件&#xff0c;没有预定义的单…

jQuery三级下拉菜单

演示地址:http://www.corange.cn/demo/3738/index.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"&g…

linux gcc march arch,Gcc的spec中arch什么的指定

gcc/gcc.c中的set_collect_gcc_options这里面有COLLECT_GCC_OPTIONS-marcharmv4t -mtunearm920t(gdb) p switches[0]$15 {part1 0x80792b1 "marcharmv4t", args 0x0, live_cond 1,validated 1 \001, ordering 0 \000}(gdb) p switches[1]$16 {part1 0x80792c…

php如何解决中文乱码问题?

为什么会出现中文乱码&#xff1f; 很多新手朋友学习PHP的时候&#xff0c;发现程序中的中文在输出的时候会出现乱码的问题&#xff0c;那么为什么会出现这种乱码的情况呢&#xff1f;一般来说&#xff0c;乱码的出现有2种原因&#xff0c;一种是由于编码(charset) 设置错误&am…

红帽将召开“开放你的世界”在线论坛

国外媒体报道&#xff0c;美国时间5月27日&#xff0c;红帽公司将召开在线开源论坛&#xff0c;主题为“开放你的世界”。时间为美国东部时间8:45-17:30.该论坛讨论的议题包括opensource.com网站所覆盖的健康医疗、教 育、政府、法律等领域。论坛嘉宾包括这些领域的开源思考者及…

Java提取文本文档中的所有网址(小案例介绍正则基础知识)

正则表达式基础以及Java中使用正则查找 定义&#xff1a; 正则表达式是一些用来匹配和处理文本的字符串 正则的基础&#xff08;先大致了解下&#xff09; 1. 正则表达式的作用 查找特定的信息&#xff08;搜索&#xff09;替换一些文本&#xff08;替换&#xff09;2. 正则基础…

Windows与Linux之间海量文件的传输与Linux下大小写敏感问题

Windows与Linux之间海量文件的传输与Linux下大小写敏感问题 mount.cifs 支持通过网络文件系统挂载&#xff0c;不过需要安装cifs-utils&#xff0c;也可通过mount -t cifs挂载&#xff0c;详细的选项可参见man mount.cifs 1. 通过Windows共享文件夹 1.1 设置windows共享1.2 Lin…

c语言如何读取mp3歌曲信息,VC中读取mp3文件信息的方法

标准格式的mp3文件中&#xff0c;都有一些自身描述的信息&#xff0c;比如歌曲名称、歌手、专辑名称等信息。这些信息都记录在mp3文件中&#xff0c;而且格式是固定的。那么&#xff0c;我们就可以用编程的方式来获取这些信息。其实说简单一点&#xff0c;就是VC文件读取的操作…

kvm虚拟机热迁移

1. 迁移介绍 迁移&#xff1a; 系统的迁移是指把源主机上的操作系统和应用程序移动到目的主机&#xff0c;并且能够在目的主机上正常运行。在没有虚拟机的时代&#xff0c;物理机之间的迁移依靠的是系统备份和恢复技术。在源主机上实时备份操作系统和应用程序的状态&#xff0c…

通过图表简化sql语句的表关联

在之前的博文中分享过一个执行了两天的一条sql语句&#xff0c;走了两个大表的扫描&#xff0c;导致执行时间很长&#xff0c;通过简化sql做了不小的改进&#xff0c;今天我们来看看还可以做些什么。 上次简化后的语句如下&#xff1a;with tmp_logical_date as (SELECT logica…

[翻译] BFKit

BFKit BFKit is a collection of useful classes to develop Apps faster. BFKit是一个有用的工具集合&#xff0c;帮助你快速开发。 Installing and Usage Pod Pod安装 Create a Podfile in your project directoryWrite:platform :ios, 7.0xcodeproj Project.xcodeproj pod …

Camera Vision - video surveillance on C#

http://www.codeproject.com/KB/audio-video/cameraviewer.aspx 开发的资源 介绍&#xff1a;纵观当今的监控系统的发展趋势&#xff0c;能很容易发现基于IP的解决方案正在迅速的普及。有许多的制造商&#xff0c;提供广泛的IP视频射像和视频服务器&#xff0c;意味着个人的IP…

11次作业

1、实验要求&#xff1a;建立一个通信录&#xff0c;通信录的结构体记录包括&#xff1a;姓名、生日、电话号码&#xff1b;其中生日又包括三项&#xff1a;年、月、日。编写程序&#xff0c;定义一个嵌套的结构类型&#xff0c;输入n&#xff08;n<10&#xff09;个联系人的…

android内存卡测试,安卓sd卡真假检测工具_内存卡检测扩容卡软件_sd insight

内存卡检测扩容卡软件内存卡检测扩容卡软件由于U盘、TF卡&#xff0c;sd内存卡等移动存储设备越来越便宜&#xff0c;导致很在某宝上买到便宜且容量大的U盘或者内存卡&#xff0c;结果基本上都是扩容盘&#xff0c;所谓扩容盘&#xff0c;就是实际容量比如2G的U盘&#xff0c;经…