【题目链接】

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. MIT算法导论——第四讲.Quicksort

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  2. 示例:Servlet显示当前系统时间(时间格式化)

    package com.mhb; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDate ...

  3. 机器人学 —— 轨迹规划(Introduction)

    轨迹规划属于机器人学中的上层问题,其主要目标是计划机器人从A移动到B并避开所有障碍的路线. 1.轨迹计划的对象 轨迹规划的对象是map,机器人通过SLAM获得地map后,则可在地图中选定任意两点进行轨 ...

  4. VS2015中的异常配置

    The New Exception Settings Window in Visual Studio 2015Managing Exceptions with the Debugger Underst ...

  5. windows 下 apache设置

    apache,apache配置,配置端口 mac下apache配置 添加虚拟主机: Alias /selftest/ "D:/self-test/" <Directory & ...

  6. fil_system_struct

    /** The tablespace memory cache */ typedef struct fil_system_struct fil_system_t; /** The tablespace ...

  7. UVa 10820 (打表、欧拉函数) Send a Table

    题意: 题目背景略去,将这道题很容易转化为,给出n求,n以内的有序数对(x, y)互素的对数. 分析: 问题还可以继续转化. 根据对称性,我们可以假设x<y,当x=y时,满足条件的只有(1, 1 ...

  8. Sublime-text markdown with Vim mode and auto preview

    说明 最近看到markdown相关的东西,被其书写方式吸引,其实以前就在找这种类似的工具,但是也没找到,由于习惯了Vim,可Vim不支持markdown预览,这点可能不是很好,于是找到Sublime- ...

  9. vim 支持 markdown 语法

    /************************************************************************* * vim 支持 markdown 语法 * 说明 ...

  10. POJ 1664 放苹果

    放苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24985   Accepted: 15908 Description ...