• 【NOI2011】阿狸的打字机


    题面

    https://www.luogu.org/problem/P2414

    题解

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #define ri register int
    #define N 100500
    using namespace std;
    char s[N];
    int m,poi[N],dfx[N],dfy[N],cc,tot;
    vector<int> son[N];
    struct node {
      int l,r,id;
    } q[N];
    vector<node> qq[N];
    
    int ff[N],ch[N][26];
    int sun[N][26];
    int nex[N];
    int ans[N],p;
    
    
    struct tree{
      int tt[N];
      void insert(int x,int k) {
        for (ri i=x;i<=cc;i+=(i&(-i))) tt[i]+=k;
      }
      int query(int x,int y) {
        int sum1=0,sum2=0;
        for (ri i=x-1;i;i-=(i&(-i))) sum1+=tt[i];
        for (ri i=y;i;i-=(i&(-i))) sum2+=tt[i];
        return sum2-sum1;
      }
    } t;
    
    void dfs(int x){
      dfx[x]=++cc;
      for (ri i=0;i<son[x].size();i++) dfs(son[x][i]);
      dfy[x]=cc;
    }
    
    void build() {
      queue<int> q;
      for (ri i=0;i<26;i++) if(ch[0][i]) q.push(ch[0][i]);
      while (!q.empty()) {
        int x=q.front(); q.pop();
        for (ri i=0;i<26;i++) {
          int y=ch[x][i];
          if (!y) ch[x][i]=ch[nex[x]][i]; else nex[y]=ch[nex[x]][i],q.push(y);
        }
      }
    }
    
    void solve(int x){
      t.insert(dfx[x],1);
      for (ri i=0;i<qq[x].size();i++) {
        ans[qq[x][i].id]=t.query(dfx[poi[qq[x][i].l]],dfy[poi[qq[x][i].l]]);
      }
      for (ri i=0;i<26;i++) if (sun[x][i]) solve(sun[x][i]);
      t.insert(dfx[x],-1);
    }
    
    int n;
    int main(){
      scanf("%s",s+1);
      int n=strlen(s+1);
      int cur=0,cnt=0;
      tot=0;
      for (ri i=1;i<=n;i++) {
        if (s[i]=='B') cur=ff[cur];
        else if (s[i]=='P') poi[++cnt]=cur;
        else if (s[i]>='a' && s[i]<='z') {
          int c=s[i]-'a';
          if (!ch[cur][c]) sun[cur][c]=ch[cur][c]=++tot,ff[tot]=cur;
          cur=ch[cur][c];
        }
      }
      build();
      for (ri i=1;i<=tot;i++) son[nex[i]].push_back(i);
      cc=0;
      dfs(0);
      scanf("%d",&m);
      for (ri i=1;i<=m;i++) {
        scanf("%d %d",&q[i].l,&q[i].r);
        q[i].id=i;
        qq[poi[q[i].r]].push_back(q[i]);
      }
      solve(0);
      for (ri i=1;i<=m;i++) printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    怎样理解HTMLCollection接口
    怎样单独遍历NodeList的键、值和键值对
    怎样获取NodeList某位置上的节点
    怎样遍历NodeList对象
    怎样理解NodeList的动态集合与静态集合
    怎样将类似数组的对象转换为数组
    怎样理解 instanceof
    怎样清理当前节点下的所有文本节点
    怎样移除当前节点
    怎样判断一个节点是否相等 / 是否相同
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279505.html
Copyright © 2020-2023  润新知