• Bzoj2434 [Noi2011]阿狸的打字机


    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 2536  Solved: 1415

    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

    Source

    先把字符串建成AC自动机,然后对fail指针建立DFS序,利用DFS序来差分答案。

    默默打开了hzw学长的博客,默默开抄。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 #include<vector>
      7 #define LL long long
      8 using namespace std;
      9 const int mxn=100010;
     10 int read(){
     11     int x=0,f=1;char ch=getchar();
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return x*f;
     15 }
     16 struct edge{int v,nxt;}e[mxn<<1];
     17 int hd[mxn],mct=0;
     18 void add_edge(int u,int v){
     19     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
     20 }
     21 vector<int>ask[mxn];//询问
     22 vector<int>id[mxn];
     23 int ans[mxn];
     24 //
     25 int n,m;
     26 char s[mxn];
     27 int ind[mxn],outd[mxn],sz=0;
     28 int tr[mxn<<1];
     29 void add(int x,int v){while(x<=sz){tr[x]+=v;x+=x&-x;}}
     30 int smm(int x){
     31     int res=0;
     32     while(x){res+=tr[x];x-=x&-x;}
     33     return res;
     34 }
     35 int pos[mxn],sct=0;
     36 struct Aca{
     37     int t[mxn][26],fail[mxn];
     38     int fa[mxn];
     39     int rt,cnt;
     40     void clear(){cnt=1;rt=1;for(int i=0;i<26;i++)t[0][i]=1;}
     41     void insert(char s[]){
     42         int now=rt;
     43         int len=strlen(s);
     44         for(int i=0;i<len;i++){
     45             if(s[i]=='P'){pos[++sct]=now;continue;}
     46             else if(s[i]=='B'){now=fa[now];continue;}
     47             if(!t[now][s[i]-'a']){
     48                 t[now][s[i]-'a']=++cnt;
     49                 fa[t[now][s[i]-'a']]=now;
     50             }
     51             now=t[now][s[i]-'a'];
     52         }
     53     }
     54     void Build(){
     55         queue<int>q;
     56         q.push(rt);
     57         fail[1]=0;
     58         while(!q.empty()){
     59             int now=q.front();q.pop();
     60             for(int i=0;i<26;i++){
     61                 if(t[now][i]){
     62                     int k=fail[now];
     63                     while(!t[k][i])k=fail[k];
     64                     fail[t[now][i]]=t[k][i];
     65                     q.push(t[now][i]);
     66                 }
     67             }
     68         }
     69     }
     70 }aca;
     71 void DFS(int u){
     72     ind[u]=++sz;
     73     for(int i=hd[u];i;i=e[i].nxt){
     74         DFS(e[i].v);
     75     }
     76     outd[u]=++sz;
     77     return;
     78 }
     79 int main()
     80 {
     81     int i,j,u,v;
     82     scanf("%s",s);
     83     n=strlen(s);
     84     aca.clear();
     85     aca.insert(s);
     86     aca.Build();
     87     for(int i=aca.rt;i<=aca.cnt;i++){
     88         add_edge(aca.fail[i],i);
     89     }
     90     DFS(0);
     91     m=read();
     92     for(i=1;i<=m;i++){
     93         u=read();v=read();
     94         ask[v].push_back(u);
     95         id[v].push_back(i);
     96     }
     97     int now=aca.rt;int t=0;
     98     //
     99     add(ind[1],1);//add(outd[1],-1);
    100     for(i=0;i<n;i++){
    101 //      printf("now: %c 
    ",s[i]);
    102         if(s[i]=='P'){
    103             t++;
    104             u=t;
    105             for(j=0;j<ask[u].size();j++){
    106                 v=pos[ask[u][j]];
    107 //              printf("%d to %d
    ",ind[v],outd[v]);
    108 //              printf("%d %d
    ",smm(outd[v]),smm(ind[v]-1));
    109                 ans[id[u][j]]=smm(outd[v])-smm(ind[v]-1);
    110             }
    111             continue;
    112         }
    113         else if(s[i]=='B'){
    114             add(ind[now],-1);//add(outd[now],1);
    115             now=aca.fa[now];continue;
    116         }
    117         now=aca.t[now][s[i]-'a'];
    118         add(ind[now],1);//add(outd[now],-1);
    119     }
    120     //
    121     for(i=1;i<=m;i++)printf("%d
    ",ans[i]);
    122     return 0;
    123 }
  • 相关阅读:
    德国10马克,高斯正态分布函数
    安装python的第三方库 geopandas
    Python版本的GDAL 安装
    [原创]App崩溃率统计工具推荐
    用户增长模型AARRR模型
    [原创]nginx日志分析工具
    [原创]浅谈移动互联网创业公司工具类产品
    [原创]浅谈在创业公司对PMF的理解
    [原创]浅谈创业公司如何选择产品方向
    [原创]浅谈在创业公司对MVP的理解
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6216433.html
Copyright © 2020-2023  润新知