bzoj3439: Kpm的MC密碼(主席樹+DFS序+字典樹)
題目傳送門
做這題有人跟我說用連結串列。處理相同的串。
網上都說要。。
其實不用吧。。記錄每個串的結尾是在字典樹上哪個點就行啊。
然後一個一個插啊。
解法:
因為是字尾所以到這建字典樹。
然後kpm串肯定是子樹的所有串。
那麼用主席樹維護子樹第k小。
要求編號連續就套個dfs序就行了。
程式碼實現:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct Trie {int son[31];Trie() {memset(son,-1,sizeof(son));}}tr[310000];
int tot,end[110000],root;char ss[310000];
void Build(int k) {
int x=root,len=strlen(ss+1);
for(int i=len;i>=1;i--) {
int y=ss[i]-'a'+1;
if(tr[x].son[y]==-1) {tot++;tr[x].son[y]=tot;}
x=tr[x].son[y];
}
end[k]=x;
}
struct node {int lc,rc,c;}t[2100000];int cnt,rt[110000];
void build(int &u,int l,int r,int p,int c) {
if(u==0)u=++cnt;t[u].c+=c;
if(l==r)return ;int mid=(l+r)/2;
if(p<=mid)build(t[u].lc,l,mid,p,c);
else build(t[u].rc,mid+1,r,p,c);
}
void Merge(int &u1,int u2) {
if(u1==0){u1=u2;return ;}if(u2==0)return ;
t[u1].c+=t[u2].c;
Merge(t[u1].lc,t[u2].lc);Merge(t[u1].rc,t[u2].rc);
}
int z,st[310000],ed[310000];
void dfs(int x) {
st[x]=++z;
for(int i=1;i<=26;i++)if(tr[x].son[i]!=-1)dfs(tr[x].son[i]);
ed[x]=z;
}
int find(int u1,int u2,int l,int r,int k) {
if(t[u1].c-t[u2].c<k)return -1;
if(l==r)return l;int mid=(l+r)/2;
int c=t[t[u1].lc].c-t[t[u2].lc].c;
if(k<=c)return find(t[u1].lc,t[u2].lc,l,mid,k);
else return find(t[u1].rc,t[u2].rc,mid+1,r,k-c);
}
int find_l(int u1,int u2,int l,int r,int p) {
if(l==r)return t[u1].c-t[u2].c;int mid=(l+r)/2;
int c=t[t[u1].lc].c-t[t[u2].lc].c;
if(p<=mid)return find(t[u1].lc,t[u2].lc,l,mid,p);
else return find(t[u1].rc,t[u2].rc,mid+1,r,p)+c;
}
int main() {
int n;scanf("%d",&n);root=tot=0;
for(int i=1;i<=n;i++) {scanf("%s",ss+1);Build(i);}
z=0;dfs(root);cnt=0;
for(int i=1;i<=n;i++)build(rt[st[end[i]]],1,n,i,1);
for(int i=1;i<=z;i++)Merge(rt[i],rt[i-1]);
for(int i=1;i<=n;i++) {
int x,k;scanf("%d",&k);x=end[i];printf("%d\n",find(rt[ed[x]],rt[st[x]-1],1,n,k));
}
return 0;
}
相關文章
- 樹的DFS序
- bzoj2809: [Apio2012]dispatching(DFS序+主席樹)API
- 主席樹
- bzoj1146: [CTSC2008]網路管理Network(dfs序+主席樹+樹狀陣列)陣列
- DFS樹
- 主席樹模板
- Trie樹,字典樹
- 從 dfs 序求 lca 到虛樹到樹分塊 學習筆記筆記
- 字典樹
- 動態主席樹模板
- AC自動機+字典序+樹狀陣列陣列
- 字典樹(Trie)
- 字典樹Trie
- 字典樹的應用
- POJ3321 Apple Tree(DFS序 + 樹狀陣列)APP陣列
- 資料結構之樹( 線段樹,字典樹)資料結構
- 字典樹(字首樹)簡單實現
- 字典樹學習
- 字典樹專題
- 【演算法】二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的遞迴和迭代實現記錄(Java版)演算法二叉樹遞迴Java
- 演算法隨筆——主席樹(可持久化線段樹)演算法持久化
- 【資料結構】淺談主席樹資料結構
- SPOJ TTM To the moon(主席樹+區間操作)
- codevs 4189 字典【字典樹】dev
- 【主席樹】P3919 【模板】可持久化線段樹 1持久化
- BZOJ4299: Codechef FRBSUM(主席樹)
- (樹)根據中序後序構建二叉樹二叉樹
- 資料結構-字典樹資料結構
- 一些“字典樹”典
- DFS在二叉樹上的表現二叉樹
- 樹莓派 | 修改樹莓派3熱點的名稱和密碼樹莓派密碼
- hihocoder 1192 簡單的樹嵌入 (樹上DFS 構造 好題)
- dfs序
- 樹的拓撲序計數
- 2024年3月21日 懸繩法 + 珂朵莉樹(ODT) + 主席樹
- 字典樹及其C++實現C++
- SPOJ DQUERY (離線數狀陣列||線上主席樹)陣列
- bzoj4477: [Jsoi2015]字串樹(主席樹+Hash+Lca)JS字串