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组询问,每组询 ...
随机推荐
- cocos2d-x step by step(2) 鼠标事件,键盘事件,等等事件
各种小控件加载进去了,那么问题来了,这些东西如何接受事件呢? good job,let us find the answer 首先我们去看文档,官方尼玛有好多文档,而且大,全,详细,感觉还是不错的 h ...
- Android--绑定服务调用服务的方法
Service依照其启动的方式,可分为两种: 1.Started Started的Service.通过在Application里用startService(Intent intent)方法来启动.这样 ...
- java性能监控工具jps-windows
jps Lists the instrumented Java Virtual Machines (JVMs) on the target system. This command is experi ...
- Populating Next Right Pointers in Each Node I, II——生成next树
1. Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...
- js eval 解析字符串
//带变量的字符串var str = 'var a=1; var b=2;'; eval(str); alert(a+b);//结果 3: //数组字符串var arrStr = "[1,2 ...
- Python web 框架:web.py
web.py 是一个Python 的web 框架,它简单而且功能强大.web.py 是公开的,无论用于什么用途都是没有限 制的. web.py 安装: pip install web.py 下面开始我 ...
- OpenGL 与 GLSL 版本号
来自:https://github.com/mattdesl/lwjgl-basics/wiki/GLSL-Versions You can use the #version command as t ...
- iphone手机连接USB时出现须要Mobile device setup disk上的usbaapl.sys文件
问题: iphone5 手机连接USB出现例如以下弹框 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYW5nZWwyMnh1/font/5a6L5L2T/ ...
- 热烈庆祝UE4完全免费Free---GitHub的关联方式
热烈庆祝UE4完全免费Free---GitHub的关联方式 时间:2015-03-03 18:38:52 阅读:3007 评论:0 收藏:0 [点我收藏+] 标 ...
- 搭建基于Jenkins的CI服务器
安装Jenkins和创建任务这些操作网上一搜一大把,这里就没必要写了,直接就开始编译.单元测试,覆盖,git提交触发构建,构建失败发送给提交人邮件. 因为项目比较复杂,为了懒省事我直接在CI服务器上安 ...