zoukankan      html  css  js  c++  java
  • BZOJ 2434 [NOI2011]阿狸的打字机

    题面:

    2434: [Noi2011]阿狸的打字机

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 3261  Solved: 1795
    [Submit][Status][Discuss]

    Description

     阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。
    经阿狸研究发现,这个打字机是这样工作的:
    l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后)。
    l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失。
    l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失。
    例如,阿狸输入aPaPBbP,纸上被打印的字符如下:
    a
    aa
    ab
    我们把纸上打印出来的字符串从1开始顺序编号,一直到n。打字机有一个非常有趣的功能,在打字机中暗藏一个带数字的小键盘,在小键盘上输入两个数(x,y)(其中1≤x,y≤n),打字机会显示第x个打印的字符串在第y个打印的字符串中出现了多少次。
    阿狸发现了这个功能以后很兴奋,他想写个程序完成同样的功能,你能帮助他么?

    Input

     输入的第一行包含一个字符串,按阿狸的输入顺序给出所有阿狸输入的字符。
    第二行包含一个整数m,表示询问个数。
    接下来m行描述所有由小键盘输入的询问。其中第i行包含两个整数x, y,表示第i个询问为(x, y)。

    Output

     输出m行,其中第i行包含一个整数,表示第i个询问的答案。

    Sample Input

    aPaPBbP
    3
    1 2
    1 3
    2 3

    Sample Output

    2
    1
    0

    HINT

     1<=N<=10^5

    1<=M<=10^5

    输入总长<=10^5

    如果对于每次询问都暴力查询肯定会TLE(废话!)。

    我们可以建出fail树(将fail指针反向),那么串x在串y中出现次数就是代表y的节点到根的路径上,

    在x的fai子树中节点的个数(可以画图归纳得出)。然后就用DFS序和树状数组离线处理。

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<vector>
      5 using namespace std;
      6 #define maxn 100001
      7 int n,m;
      8 int haha[maxn];
      9 int read()
     10 {
     11     char s=getchar();
     12     int a=0;
     13     while(s<'0'||s>'9')
     14         s=getchar();
     15     while(s>='0'&&s<='9')
     16     {
     17         a=a*10+s-'0';
     18         s=getchar();
     19     }
     20     return a;
     21 }
     22 class fenwick_tree
     23 {
     24     private:
     25         #define lowbit(x) x&(-x)
     26         int c[maxn];
     27     public:
     28         fenwick_tree()
     29         {
     30             memset(c,0,sizeof(c));
     31         }
     32         inline void update(int x,int w)
     33         {
     34             for(;x<=n;x+=lowbit(x))c[x]+=w;
     35         }
     36         inline int query(int x)
     37         {
     38             int ans=0;
     39             for(;x>0;x-=lowbit(x))ans+=c[x];
     40             return ans;
     41         }
     42 }bit;
     43 class AC_auto
     44 {
     45     public:
     46         struct node
     47         {
     48             int id,flag,l,r;
     49             node *son[26],*fa,*fail;
     50         }*root,tree[maxn],*q[maxn],*print[maxn];
     51         int indx,head,tail,cnt,num;
     52         struct edge
     53         {
     54             node *u,*v;
     55             int nex;
     56         }edges[maxn];
     57         int nxt[maxn],edge_cnt,dfn;
     58         node *newnode(int id,node *f)
     59         {
     60             node *t;t=&tree[indx++];
     61             t->id=id;t->fa=f;t->fail=NULL;
     62             for(int i=0;i<26;i++)t->son[i]=NULL;
     63             return t;
     64         }
     65         AC_auto()
     66         {
     67             edge_cnt=0;
     68             memset(nxt,0,sizeof(nxt));
     69             cnt=0;num=0;dfn=0;
     70             indx=0;head=1;tail=0;
     71             root=newnode(0,NULL);
     72         }
     73         void insert(char *key)
     74         {
     75             node *t=root;char *p=key;
     76             
     77             while(*p)
     78             {
     79                 if(*p=='P')
     80                 {
     81                     t->flag=++cnt;print[cnt]=t;
     82                 }
     83                 else
     84                     if(*p=='B')t=t->fa;
     85                     else
     86                     {
     87                         if(!t->son[*p-'a'])
     88                             t->son[*p-'a']=newnode(++num,t);
     89                         t=t->son[*p-'a'];
     90                     }
     91                 ++p;
     92             }
     93         }
     94         void bfs()
     95         {
     96             node *t,*p;q[++tail]=root;
     97             while(head<=tail)
     98             {
     99                 t=q[head++];
    100                 for(int i=0;i<26;i++)
    101                     if(t->son[i])
    102                     {
    103                         p=t->fail;
    104                         while(p&&!p->son[i])p=p->fail;
    105                         t->son[i]->fail=p?p->son[i]:root;
    106                         q[++tail]=t->son[i];
    107                     }
    108             }
    109         }
    110         void add(node *u,node *v)
    111         {
    112             edges[++edge_cnt]=(edge){u,v,nxt[u->id]};
    113             nxt[u->id]=edge_cnt;
    114         }
    115         void build_failtree(node *t)
    116         {
    117             for(int i=0;i<26;i++)
    118                 if(t->son[i])
    119                 {
    120                     add(t->son[i]->fail,t->son[i]);build_failtree(t->son[i]);
    121                 }
    122         }
    123         void dfs(node *t)
    124         {
    125             t->l=++dfn;
    126             for(int i=nxt[t->id];i;i=edges[i].nex)
    127                 if(edges[i].v!=NULL)
    128                     dfs(edges[i].v);
    129             t->r=dfn;
    130         }
    131         struct QAQ
    132         {
    133             int id;node *t;
    134         };
    135         vector<QAQ>QWQ[maxn];
    136         void work(node *t)
    137         {
    138             bit.update(t->l,1);
    139             int s=QWQ[t->id].size();
    140             QAQ ss;
    141             for(int i=0;i<s;i++)
    142             {
    143                 ss=QWQ[t->id][i];
    144                 haha[ss.id]=bit.query(ss.t->r)-bit.query(ss.t->l-1);
    145             }
    146             for(int i=0;i<26;i++)
    147                 if(t->son[i]!=NULL)
    148                     work(t->son[i]);
    149             bit.update(t->l,-1);
    150         }
    151 }ac_auto;
    152 char s[maxn];
    153 int main()
    154 {
    155     int x,y;
    156     scanf("%s",s);
    157     n=strlen(s);
    158     ac_auto.insert(s);
    159     ac_auto.bfs();
    160     ac_auto.build_failtree(ac_auto.root);
    161     ac_auto.dfs(ac_auto.root);
    162     scanf("%d",&m);
    163     for(int i=1;i<=m;i++)    
    164     {
    165         scanf("%d%d",&x,&y);    
    166         ac_auto.QWQ[ac_auto.print[y]->id].push_back((AC_auto::QAQ){i,ac_auto.print[x]});
    167     }
    168     ac_auto.work(ac_auto.root);
    169     for(int i=1;i<=m;i++)
    170         printf("%d
    ",haha[i]);
    171 }
    BZOJ 2434
  • 相关阅读:
    小知识!
    命令级的python静态资源服务。
    自定义滚动条样式-transition无效
    css:a:visited限制
    react16 渲染流程
    virtual-dom
    用video标签流式加载
    golang 代码笔记
    position:fixed not work?
    go/node/python 多进程与多核cpu
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7181434.html
Copyright © 2011-2022 走看看