【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=3439

【题意】

给定若干串,问一个串的作为其后缀的给定串集合中的第k小。

【思路】

如果将每个串反向,则问题为一个串作为其前缀的给定串集合的第k小。

如果用Trie组织数据,则发现该串对应的集合即为以Trie上以尾节点为根的子树。我们按照dfs序构造序列,则问题即为连续区间上的第k大,可以用主席树求出。

注意有重复的串。

【代码】

 #include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 1e6+; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} char s[N];
int n,m,dfsc,L[N],R[N],dfs_list[N],sz; struct Trie {
int ch[N][],sz;
vector<int> num[N];
Trie() {
sz=;
memset(ch,,sizeof(ch));
}
void insert(char *s,int val) {
int u=;
for(int i=;s[i];i++) {
int c=s[i]-'a';
if(!ch[u][c]) ch[u][c]=++sz;
u=ch[u][c];
}
num[u].push_back(val);
}
void dfs(int u)
{
int tmp=dfsc+;
FOR(i,,(int)num[u].size()-) {
dfs_list[++dfsc]=num[u][i];
L[num[u][i]]=tmp;
}
FOR(c,,) if(ch[u][c])
dfs(ch[u][c]);
FOR(i,,(int)num[u].size()-)
R[num[u][i]]=dfsc;
}
} trie; struct Tnode {
Tnode *ch[];
int num;
void * operator
new(size_t size,Tnode *l,Tnode *r,int x) ;
}*T[N],*mempool,*G;
//´óСΪ 1<<15 µÄÄÚ´æ³Ø
void *Tnode::operator new (size_t size,Tnode *l,Tnode*r,int x) {
if(G==mempool) {
G=new Tnode[<<];
mempool=G+(<<);
memset(G,,sizeof(Tnode)*(<<));
}
G->ch[]=l,G->ch[]=r,G->num=x;
return G++;
} Tnode* build(Tnode* p,int l,int r,int val) {
int mid=l+r>>;
if(l==r) return new (0x0,0x0,p->num+)Tnode;
if(val<=mid)
return new (build(p->ch[],l,mid,val),p->ch[],p->num+)Tnode;
else
return new (p->ch[],build(p->ch[],mid+,r,val),p->num+)Tnode;
}
int query(Tnode *x,Tnode *y,int l,int r,int rk) {
int mid=l+r>>;
if(l==r) return mid;
int sum=y->ch[]->num - x->ch[]->num;
if(rk<=sum) return query(x->ch[],y->ch[],l,mid,rk);
else return query(x->ch[],y->ch[],mid+,r,rk-sum);
} int main()
{
n=read();
FOR(i,,n) {
scanf("%s",s);
int n=strlen(s);
for(int j=;j*<n;j++)
swap(s[j],s[n--j]);
trie.insert(s,i);
}
trie.dfs(); T[]=new (0x0,0x0,) Tnode;
T[]->ch[]=T[]->ch[]=T[]; FOR(i,,n)
T[i]=build(T[i-],,n,dfs_list[i]);
FOR(i,,n) {
int k=read();
if(k>R[i]-L[i]+) puts("-1");
else printf("%d\n",query(T[L[i]-],T[R[i]],,n,k));
}
return ;
}

bzoj 3439 Kpm的MC密码(Trie+dfs序+主席树)的更多相关文章

  1. BZOJ 3439: Kpm的MC密码( trie + DFS序 + 主席树 )

    把串倒过来插进trie上, 那么一个串的kpm串就是在以这个串最后一个为根的子树, 子树k大值的经典问题用dfs序+可持久化线段树就可以O(NlogN)解决 --------------------- ...

  2. BZOJ 3439: Kpm的MC密码 (trie+dfs序主席树)

    题意 略 分析 把串倒过来插进trietrietrie上, 那么一个串的kpmkpmkpm串就是这个串在trietrietrie上对应的结点的子树下面的所有字符串. 那么像 BZOJ 3551/354 ...

  3. bzoj 3439: Kpm的MC密码 Trie+动态开点线段树

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3439 题解: 首先我们发现这道题要查的是后缀不是前缀. 如果查前缀就可以迅速查找到字符串 ...

  4. BZOJ 3439 Kpm的MC密码 (Trie树+线段树合并)

    题面 先把每个串反着插进$Trie$树 每个节点的子树内,可能有一些节点是某些字符串的开头 每个节点挂一棵权值线段树,记录这些节点对应的原来字符串的编号 查询的时候在线段树上二分即可 为了节省空间,使 ...

  5. BZOJ 3439 Kpm的MC密码

    倒着建trie,然后主席树来求子树第k大. #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  6. BZOJ-3439:Kpm的MC密码(Trie+DFS序+主席树)

    背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身份验证问题了... 描述 ...

  7. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  8. 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)

    传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...

  9. 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树

    bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...

随机推荐

  1. GIT权威手册及常用命令用法

    http://git-scm.com/book/zh Git Stash用法 http://www.cppblog.com/deercoder/archive/2011/11/13/160007.ht ...

  2. c语言中static的用法

    1.static定义变量: 1).局部: a.静态局部变量在函数内部定义,生存期为整个源代码,但作用域与自动变量相同,只能在定义的函数里面使用.退出该函数后,虽然此变量还存在内存中,但不能使用. b. ...

  3. 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)

    这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...

  4. ggplot2 demo

    title <- rep("A Really Rather Long Text Label", 25)value <- runif(25, 1,10)spacing & ...

  5. iOS学习笔记:iOS核心动画中的常用类型

    CATransaction 当我们在自定义的图层上修改某些支持动画的属性时,系统会为该属性的修改自动产生动画.这种其实属于隐式动画.隐式动画要得益于CATransaction. 一个CATransac ...

  6. SGU 187 - Twist and whirl -- want to cheat

    原题地址:http://acm.sgu.ru/problem.php?contest=0&problem=187 太开心啦!!!!这道题从2013年开始困扰我!!今天晚上第四次下定决心把它写一 ...

  7. 函数rec_get_nth_field_offs_old

    /************************************************************//** The following function is used to ...

  8. SQL大数据操作统计

    SQL大数据操作统计 1:select count(*) from table的区别SELECT object_name(id) as TableName,indid,rows,rowcnt FROM ...

  9. asp.net获取文件夹下的所有文件

    using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System. ...

  10. Dialog第三方登录等待

    1. styles.xml 中加入 <style name="loadingDialogStyle" parent="android:Theme.Dialog&qu ...