zoukankan      html  css  js  c++  java
  • [BZOJ3439]Kpm的MC密码

    题目大意:
      给定$n(nleq10^5)$个字符串$s_{1sim n}$,$n$次询问,每次询问所有满足$s_i$是$t$的后缀的$t$中,编号第$k_i$小的$t$的编号。

    思路:
      倒着建字典树,根据DFS序建立主席树,维护每个区间内编号出现次数。

     1 #include<list>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<cstring>
     5 #include<algorithm>
     6 inline int getint() {
     7     register char ch;
     8     while(!isdigit(ch=getchar()));
     9     register int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return x;
    12 }
    13 const int N=100001,logN=18,S=26;
    14 int n;
    15 class FotileTree {
    16     private:
    17         struct Node {
    18             int val,left,right,vis;
    19         };
    20         Node node[N*logN];
    21         int sz,new_node(const int &p,const int &id) {
    22             node[++sz]=node[p];
    23             node[sz].vis=id;
    24             return sz;
    25         }
    26     public:
    27         int root[N];
    28         void modify(int &p,const int &b,const int &e,const int &x,const int &y,const int &id) {
    29             if(node[p].vis!=id) p=new_node(p,id);
    30             node[p].val+=y;
    31             if(b==e) return;
    32             const int mid=(b+e)>>1;
    33             if(x<=mid) modify(node[p].left,b,mid,x,y,id);
    34             if(x>mid) modify(node[p].right,mid+1,e,x,y,id);
    35         }
    36         int query(const int &p,const int &q,const int &b,const int &e,const int &k) {
    37             if(node[q].val-node[p].val<k) return -1;
    38             if(b==e) return b;
    39             const int mid=(b+e)>>1;
    40             if(node[node[q].left].val-node[node[p].left].val>=k) return query(node[p].left,node[q].left,b,mid,k);
    41             return query(node[p].right,node[q].right,mid+1,e,k-(node[node[q].left].val-node[node[p].left].val));
    42         }
    43 };
    44 FotileTree t;
    45 class Trie {
    46     private:
    47         int pos[N],ch[N][S],par[N],dfn[N],size[N],cnt;
    48         std::list<int> val[N];
    49         int sz,new_node(const int &p) {
    50             par[++sz]=p;
    51             return sz;
    52         }
    53         int idx(const char &c) const {
    54             return c-'a';
    55         }
    56         void push_up(const int &p) {
    57             size[p]=1;
    58             for(register int i=0;i<S;i++) size[p]+=size[ch[p][i]];
    59         }
    60     public:
    61         void insert(const char s[],const int &id) {
    62             int u=0;
    63             for(register int i=0;s[i];i++) {
    64                 u=ch[u][idx(s[i])]=ch[u][idx(s[i])]?:new_node(u);
    65             }
    66             val[pos[id]=u].push_back(id);
    67             for(;u;u=par[u]) push_up(u);
    68         }
    69         void dfs(const int &x) {
    70             dfn[x]=cnt++;
    71             if(dfn[x]) t.root[dfn[x]]=t.root[dfn[x]-1];
    72             for(register std::list<int>::iterator i=val[x].begin();i!=val[x].end();i++) {
    73                 t.modify(t.root[dfn[x]],1,n,*i,1,dfn[x]);
    74             }
    75             for(int i=0;i<S;i++) {
    76                 if(ch[x][i]) dfs(ch[x][i]);
    77             }
    78         }
    79         int query(const int &id,const int &k) {
    80             return t.query(t.root[dfn[pos[id]]-1],t.root[dfn[pos[id]]+size[pos[id]]-1],1,n,k);
    81         }
    82 };
    83 Trie trie;
    84 char s[N];
    85 int main() {
    86     n=getint();
    87     for(register int i=1;i<=n;i++) {
    88         scanf("%s",s);
    89         std::reverse(&s[0],&s[strlen(s)]);
    90         trie.insert(s,i);
    91     }
    92     trie.dfs(0);
    93     for(register int i=1;i<=n;i++) {
    94         printf("%d
    ",trie.query(i,getint()));
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    android openGl视频
    《jQuery权威指南》学习笔记之第2章 jQuery选择器
    RobHess的SIFT源码分析:综述
    building android/ubuntu-touch on 32bit machine
    Android开发(24)---安卓中实现多线程下载(带进度条和百分比)
    创建Sdcard
    POJ 1033 Defragment
    [C++STDlib基础]关于C标准输入输出的操作——C++标准库头文件<cstdio>
    机器学习实战决策树之眼镜男买眼镜
    protubuffer for windows配置指南!
  • 原文地址:https://www.cnblogs.com/skylee03/p/8564769.html
Copyright © 2011-2022 走看看