首页 > 代码库 > [BZOJ3439]Kpm的MC密码
[BZOJ3439]Kpm的MC密码
看到后缀,就想到把所有串反过来插入trie中
建好trie之后dfs,答案其实就是当前结点的子树中的第k大
按dfs的顺序给节点编号,把问题转化为求区间第k大
那么就用可持久化线段树就好了
1 #include<stdio.h> 2 #include<vector> 3 #include<string.h> 4 using namespace std; 5 struct trienode{ 6 int ch[26]; 7 vector<int>ids; 8 }trie[300010]; 9 struct seg{ 10 int lson,rson,size; 11 }tr[2000010]; 12 int n,trietot,sttot,clk,root[100010],ans[100010],ki[100010]; 13 void trieinsert(int id,int x,char*s,int p){ 14 if(p<0){ 15 trie[x].ids.push_back(id); 16 return; 17 } 18 if(trie[x].ch[s[p]-‘a‘]==0){ 19 trietot++; 20 trie[x].ch[s[p]-‘a‘]=trietot; 21 } 22 trieinsert(id,trie[x].ch[s[p]-‘a‘],s,p-1); 23 } 24 void stinsert(int preroot,int root,int l,int r,int v){ 25 tr[root].size=tr[preroot].size+1; 26 if(l==r)return; 27 int mid=(l+r)>>1; 28 sttot++; 29 if(v<=mid){ 30 tr[root].lson=sttot; 31 tr[root].rson=tr[preroot].rson; 32 stinsert(tr[preroot].lson,sttot,l,mid,v); 33 }else{ 34 tr[root].lson=tr[preroot].lson; 35 tr[root].rson=sttot; 36 stinsert(tr[preroot].rson,sttot,mid+1,r,v); 37 } 38 } 39 int stquery(int lroot,int rroot,int l,int r,int k){ 40 if(tr[rroot].size-tr[lroot].size<k)return-1; 41 if(l==r)return l; 42 int mid=(l+r)>>1,d=tr[tr[rroot].lson].size-tr[tr[lroot].lson].size; 43 if(k<=d) 44 return stquery(tr[lroot].lson,tr[rroot].lson,l,mid,k); 45 else 46 return stquery(tr[lroot].rson,tr[rroot].rson,mid+1,r,k-d); 47 } 48 void dfs(int x){ 49 int l,i; 50 l=clk; 51 for(i=0;i<trie[x].ids.size();i++){ 52 clk++; 53 sttot++; 54 root[clk]=sttot; 55 stinsert(root[clk-1],sttot,1,n,trie[x].ids[i]); 56 } 57 for(i=0;i<26;i++){ 58 if(trie[x].ch[i])dfs(trie[x].ch[i]); 59 } 60 for(i=0;i<trie[x].ids.size();i++){ 61 ans[trie[x].ids[i]]=stquery(root[l],root[clk],1,n,ki[trie[x].ids[i]]); 62 } 63 } 64 char s[300010]; 65 int main(){ 66 int i; 67 scanf("%d",&n); 68 for(i=1;i<=n;i++){ 69 scanf("%s",s); 70 trieinsert(i,0,s,strlen(s)-1); 71 } 72 for(i=1;i<=n;i++)scanf("%d",ki+i); 73 dfs(0); 74 for(i=1;i<=n;i++)printf("%d\n",ans[i]); 75 }
[BZOJ3439]Kpm的MC密码
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。