zoukankan      html  css  js  c++  java
  • bzoj 3439 Kpm的MC密码(Trie+dfs序+主席树)

    【题目链接】

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

    【题意】

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

    【思路】

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

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

        注意有重复的串。

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int N = 1e6+100;
     15 
     16 ll read() {
     17     char c=getchar();
     18     ll f=1,x=0;
     19     while(!isdigit(c)) {
     20         if(c=='-') f=-1; c=getchar();
     21     }
     22     while(isdigit(c))
     23         x=x*10+c-'0',c=getchar();
     24     return x*f;
     25 }
     26 
     27 char s[N];
     28 int n,m,dfsc,L[N],R[N],dfs_list[N],sz;
     29 
     30 struct Trie {
     31     int ch[N][26],sz;
     32     vector<int> num[N];
     33     Trie() {
     34         sz=0;
     35         memset(ch,0,sizeof(ch));
     36     }
     37     void insert(char *s,int val) {
     38         int u=0;
     39         for(int i=0;s[i];i++) {
     40             int c=s[i]-'a';
     41             if(!ch[u][c]) ch[u][c]=++sz;
     42             u=ch[u][c];
     43         }
     44         num[u].push_back(val);
     45     }
     46     void dfs(int u) 
     47     {
     48         int tmp=dfsc+1;
     49         FOR(i,0,(int)num[u].size()-1) {
     50             dfs_list[++dfsc]=num[u][i];
     51             L[num[u][i]]=tmp;
     52         }
     53         FOR(c,0,25) if(ch[u][c])
     54             dfs(ch[u][c]);
     55         FOR(i,0,(int)num[u].size()-1)
     56             R[num[u][i]]=dfsc;
     57     }
     58 } trie;
     59 
     60 struct Tnode {
     61     Tnode *ch[2];
     62     int num;
     63     void * operator 
     64         new(size_t size,Tnode *l,Tnode *r,int x) ;
     65 }*T[N],*mempool,*G;
     66 //´óСΪ 1<<15 µÄÄÚ´æ³Ø 
     67 void *Tnode::operator new (size_t size,Tnode *l,Tnode*r,int x) {
     68     if(G==mempool) {
     69         G=new Tnode[1<<15];
     70         mempool=G+(1<<15);
     71         memset(G,0,sizeof(Tnode)*(1<<15));
     72     }
     73     G->ch[0]=l,G->ch[1]=r,G->num=x;
     74     return G++;
     75 }
     76 
     77 Tnode* build(Tnode* p,int l,int r,int val) {
     78     int mid=l+r>>1;
     79     if(l==r) return new (0x0,0x0,p->num+1)Tnode;
     80     if(val<=mid) 
     81         return new (build(p->ch[0],l,mid,val),p->ch[1],p->num+1)Tnode;
     82     else
     83         return new (p->ch[0],build(p->ch[1],mid+1,r,val),p->num+1)Tnode;
     84 }
     85 int query(Tnode *x,Tnode *y,int l,int r,int rk) {
     86     int mid=l+r>>1;
     87     if(l==r) return mid;
     88     int sum=y->ch[0]->num - x->ch[0]->num;
     89     if(rk<=sum) return query(x->ch[0],y->ch[0],l,mid,rk);
     90     else return query(x->ch[1],y->ch[1],mid+1,r,rk-sum);
     91 }
     92 
     93 int main()
     94 {
     95     n=read();
     96     FOR(i,1,n) {
     97         scanf("%s",s);
     98         int n=strlen(s);
     99         for(int j=0;j*2<n;j++)
    100             swap(s[j],s[n-1-j]);
    101         trie.insert(s,i);
    102     }
    103     trie.dfs(0);
    104     
    105     T[0]=new (0x0,0x0,0) Tnode;
    106     T[0]->ch[0]=T[0]->ch[1]=T[0];
    107     
    108     FOR(i,1,n)
    109         T[i]=build(T[i-1],1,n,dfs_list[i]);
    110     FOR(i,1,n) {
    111         int k=read();
    112         if(k>R[i]-L[i]+1) puts("-1");
    113         else printf("%d
    ",query(T[L[i]-1],T[R[i]],1,n,k));
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    c# WInform 自定义导航布局
    c# 关于DataTable
    Sql Server 表结构相关
    C# winform 文件管理
    c# SqlBulkCopy实现批量从数据集中把数据导入到数据库中
    C# winform 动态操作webService
    c# Winform实现发送邮件
    C# 网络编程 TcpListener
    1122考试T2
    1121考试总结
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5329131.html
Copyright © 2011-2022 走看看