BZOJ-3439:Kpm的MC密码(Trie+DFS序+主席树)
背景
想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的。。。),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身份验证问题了。。。
描述
Kpm当年设下的问题是这样的:
现在定义这么一个概念,如果字符串s是字符串c的一个后缀,那么我们称c是s的一个kpm串。
系统将随机生成n个由a…z组成的字符串,由1…n编号(s1,s2…,sn),然后将它们按序告诉你,接下来会给你n个数字,分别为k1…kn,对于每一个ki,要求你求出列出的n个字符串中所有是si的kpm串的字符串的编号中第ki小的数,如果不存在第ki小的数,则用-1代替。(比如说给出的字符串是cd,abcd,bcd,此时k1=2,那么”cd”的kpm串有”cd”,”abcd”,”bcd”,编号分别为1,2,3其中第2小的编号就是2)(PS:如果你能在相当快的时间里回答完所有n个ki的查询,那么你就可以成功帮kpm进入MC啦~~)
Input
第一行一个整数 n 表示字符串的数目
接下来第二行到n+1行总共n行,每行包括一个字符串,第i+1行的字符串表示编号为i的字符串
接下来包括n行,每行包括一个整数ki,意义如上题所示
Output
包括n行,第i行包括一个整数,表示所有是si的kpm串的字符串的编号中第ki小的数
Sample Input 3 cd abcd bcd 2 3 1
Sample Output 2 -1 2 样例解释 “cd”的kpm 串有”cd”,”abcd”,”bcd”,编号为1,2,3,第2小的编号是 2,”abcd”的kpm串只有一个,所以第3小的编号不存在,”bcd”的kpm 串有”abcd”,”bcd”,第1小的编号就是2。 数据范围与约定 设所有字符串的总长度为len 对于100%的数据,1<=n<=100000,0
题意:Trie树上,求某个点的子树的第K大。
思路:建立Trie树,然后跑得dfs序,然后主席树求第k大。
( 注意当Trie树上一个点代表多个串时,怎么去处理dfs序。
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int ch[maxn][],cnt,in[maxn],out[maxn],times,tot,np;
int Laxt[maxn],Next[maxn],To[maxn],a[maxn],rt[maxn];
char c[maxn];
struct node{
int l,r,sum;
node(){ l=r=sum=;}
node(int ll,int rr,int ss):l(ll),r(rr),sum(ss){}
}s[maxn*];
void add(int u,int v){
Next[++tot]=Laxt[u];
Laxt[u]=tot; To[tot]=v;
}
void insert(int opt)
{
int L=strlen(c+),Now=;
for(int i=L;i>=;i--){
if(!ch[Now][c[i]-'a']) ch[Now][c[i]-'a']=++cnt;
Now=ch[Now][c[i]-'a'];
}
add(Now,opt);
}
void dfs(int u)
{ //Trie树上同一个点可能有多个串,把他们一起排。
int num=times;
for(int i=Laxt[u];i;i=Next[i]) a[++times]=To[i];
for(int i=;i<;i++) if(ch[u][i]) dfs(ch[u][i]);
for(int i=Laxt[u];i;i=Next[i]) in[To[i]]=num,out[To[i]]=times;
}
void modify(int &Now,int pre,int L,int R,int pos)
{
Now=++np; s[Now]=node(s[pre].l,s[pre].r,s[pre].sum+);
if(L==R) return;
int Mid=(L+R)>>;
if(pos<=Mid) modify(s[Now].l,s[pre].l,L,Mid,pos);
else modify(s[Now].r,s[pre].r,Mid+,R,pos);
}
int query(int Now,int pre,int L,int R,int K)
{
if(s[Now].sum-s[pre].sum<K) return -;
if(L==R) return L;
int Mid=(L+R)>>;
if(s[s[Now].l].sum-s[s[pre].l].sum>=K) return query(s[Now].l,s[pre].l,L,Mid,K);
return query(s[Now].r,s[pre].r,Mid+,R,K-(s[s[Now].l].sum-s[s[pre].l].sum));
}
int main()
{
int N,K,i,j;
scanf("%d",&N);
for(i=;i<=N;i++){
scanf("%s",c+);
insert(i);
}
dfs();
for(i=;i<=N;i++){
modify(rt[i],rt[i-],,N,a[i]);
}
for(i=;i<=N;i++){
scanf("%d",&K);
int ans=query(rt[out[i]],rt[in[i]],,N,K);
printf("%d\n",ans);
}
return ;
}
BZOJ-3439:Kpm的MC密码(Trie+DFS序+主席树)的更多相关文章
- BZOJ 3439: Kpm的MC密码( trie + DFS序 + 主席树 )
把串倒过来插进trie上, 那么一个串的kpm串就是在以这个串最后一个为根的子树, 子树k大值的经典问题用dfs序+可持久化线段树就可以O(NlogN)解决 --------------------- ...
- BZOJ 3439: Kpm的MC密码 (trie+dfs序主席树)
题意 略 分析 把串倒过来插进trietrietrie上, 那么一个串的kpmkpmkpm串就是这个串在trietrietrie上对应的结点的子树下面的所有字符串. 那么像 BZOJ 3551/354 ...
- bzoj 3439: Kpm的MC密码 Trie+动态开点线段树
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3439 题解: 首先我们发现这道题要查的是后缀不是前缀. 如果查前缀就可以迅速查找到字符串 ...
- BZOJ 3439 Kpm的MC密码 (Trie树+线段树合并)
题面 先把每个串反着插进$Trie$树 每个节点的子树内,可能有一些节点是某些字符串的开头 每个节点挂一棵权值线段树,记录这些节点对应的原来字符串的编号 查询的时候在线段树上二分即可 为了节省空间,使 ...
- BZOJ 3439 Kpm的MC密码
倒着建trie,然后主席树来求子树第k大. #include<iostream> #include<cstdio> #include<cstring> #inclu ...
- bzoj 3439 Kpm的MC密码(Trie+dfs序+主席树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3439 [题意] 给定若干串,问一个串的作为其后缀的给定串集合中的第k小. [思路] 如 ...
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)
传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...
- 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树
bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...
随机推荐
- 在Intellij上面导入项目 & AOP示例项目 & AspectJ学习 & Spring AoP学习
为了学习这篇文章里面下载的代码:http://www.cnblogs.com/charlesblc/p/6083687.html 需要用Intellij导入一个已有工程.源文件原始内容也可见:link ...
- C#遇见的函数
1.类Stopwatch 提供一组方法和属性,可用于准确地测量运行时间. 命名空间: System.Diagnostics Stopwatch timePerParse = Stopwatc ...
- Pro Android学习笔记(一三七):Home Screen Widgets(3):配置Activity
文章转载仅仅能用于非商业性质,且不能带有虚拟货币.积分.注冊等附加条件.转载须注明出处http://blog.csdn.net/flowingflying/以及作者@恺风Wei. 通过widget定义 ...
- Linux基础(1)- 命令和目录文件
1.开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 Linux操作界面如图: 右击桌面,点击打开终端 输入“su”,点击回车键,出现密码,输入密码,点击回车键,显 ...
- 【NoSql】Redis实践篇-简单demo实现(一)
Redis是一个key-value存储系统. Redis的出现,非常大程度补偿了memcached这类key/value存储的不足,在部分场合能够对关系数据库起到非常好的补充作用 Redis是一个ke ...
- HDMI
HDMI,全称为(High Definition Multimedia Interface)高清多媒体接口,主要用于传输高清音视频信号. 现在是HDMI2.0.新一代的HDMI2.0较上一代最大的提升 ...
- 笔记03 MVVM 开发的几种模式(WPF)
转自http://www.cnblogs.com/buptzym/p/3220910.html 在WPF系(包括SL,WP或者Win8)应用开发中,MVVM是个老生常谈的问题.初学者可能不会有感觉,但 ...
- http://www.cnblogs.com/yycxbjl/archive/2010/04/20/1716689.html
http://www.cnblogs.com/yycxbjl/archive/2010/04/20/1716689.html PS: 开发工具 VS2010, 所有工程都为Debug状态,本人刚接触 ...
- Machine Learning: 一部气势恢宏的人工智能发展史
转载自:雷锋网 本文作者:陈圳 2016-09-12 09:46 导语:机器学习的从产生,发展,低潮和全盛的历史 雷锋网(公众号:雷锋网)按:本文作者DataCastle数据城堡,主要介绍了机器学习的 ...
- leetCode(51):Valid Palindrome
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...