zoukankan      html  css  js  c++  java
  • bzoj 2754 [SCOI2012]喵星球上的点名(后缀数组)

    【题目链接】

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

    【题意】

      每只喵有名姓,如果被老师点到名或姓的子串都要答道,但每只喵一次点名只答一次,问每次有多少只喵答道,以及每只喵答道多少次。

    【思路】

           后缀数组

           将所有的串连起来,包括姓名和询问。处理出rank[],sa[],height[],通过rank确定一个询问的位置,然后在height上左右各扫一下,统计即可。flag对同一只标记,kase是时间戳(也算知道叫什么了=-=)

    【代码】

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int N = 3*1e5+1e2;
      8 
      9 int s[N];
     10 int sa[N],height[N],rank[N],t[N],t2[N],c[N];
     11 
     12 void build_sa(int m,int n) {
     13     int i,k,*x=t,*y=t2;
     14     for(i=0;i<m;i++) c[i]=0;
     15     for(i=0;i<n;i++) c[x[i]=s[i]]++;
     16     for(i=0;i<m;i++) c[i]+=c[i-1];
     17     for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
     18     for(k=1;k<=n;k<<=1) {
     19         int p=0;
     20         for(i=n-k;i<n;i++) y[p++]=i;
     21         for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
     22         for(i=0;i<m;i++) c[i]=0;
     23         for(i=0;i<n;i++) c[x[y[i]]]++;
     24         for(i=0;i<m;i++) c[i]+=c[i-1];
     25         for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
     26         swap(x,y);
     27         p=1; x[sa[0]]=0;
     28         for(i=1;i<n;i++) 
     29             x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++;
     30         if(p>=n) break;
     31         m=p;
     32     }
     33 }
     34 void get_height(int n) {
     35     int i,j,k=0;
     36     for(i=0;i<n;i++) rank[sa[i]]=i;
     37     for(i=0;i<n;i++) {
     38         if(k) k--;
     39         j=sa[rank[i]-1];
     40         while(s[i+k]==s[j+k]) k++;
     41         height[rank[i]]=k;
     42     }
     43 }
     44 
     45 int n,m;
     46 int flag[N],kase,ans[N],from[N],que[N],length[N];
     47 void read(int& x) {
     48     char c=getchar(); int f=1; x=0;
     49     while(!isdigit(c)){if(c=='-')f=-1; c=getchar();}
     50     while(isdigit(c)) x=x*10+c-'0',c=getchar();
     51     x*=f;
     52 }
     53 int main() {
     54     memset(from,-1,sizeof(from));
     55     read(n),read(m);
     56     int x,len=0;
     57     for(int i=0;i<n;i++) {
     58         read(x);
     59         for(int j=0;j<x;j++)
     60             read(s[len]),from[len++]=i;
     61         s[len++]=10001;
     62         read(x);
     63         for(int j=0;j<x;j++)
     64             read(s[len]),from[len++]=i;
     65         s[len++]=10001;
     66     }
     67     for(int i=0;i<m;i++) {
     68         read(x);
     69         que[i]=len; length[i]=x;
     70         for(int j=0;j<x;j++)
     71             read(s[len++]);
     72         s[len++]=10001;
     73     }
     74     build_sa(10002,len);
     75     get_height(len);
     76     for(int i=0;i<m;i++) {
     77         int p=rank[que[i]],tot=0;
     78         ++kase;
     79         while(height[p]>=length[i]) {
     80             if(from[sa[p-1]]!=-1)
     81                 if(flag[from[sa[p-1]]]!=kase) {
     82                     flag[from[sa[p-1]]]=kase;
     83                     ++tot;
     84                     ++ans[from[sa[p-1]]];
     85                 }
     86             p--;
     87             if(!p) break;
     88         }
     89         p=rank[que[i]];
     90         while(height[p+1]>=length[i]) {
     91             if(from[sa[p+1]]!=-1)
     92                 if(flag[from[sa[p+1]]]!=kase) {
     93                     flag[from[sa[p+1]]]=kase;
     94                     ++tot;
     95                     ++ans[from[sa[p+1]]];
     96                 }
     97             p++;
     98             if(p==len) break;
     99         }
    100         printf("%d
    ",tot);
    101     }
    102     printf("%d",ans[0]);
    103     for(int i=1;i<n;i++) printf(" %d",ans[i]);
    104 }
  • 相关阅读:
    使用protobuf生成代码import包找不到
    SQL 对邮箱数据的处理(分类统计)
    Hive 集合函数 collect_set() collect_list()
    菜谱分享网站微信小程序开发说明(1)-介绍与运行
    windows 下查看端口占用
    Windows下安装Maven自定义仓库配置阿里下载源,配置Ecplise、IDEA
    Windows下安装Node.js完整详细教程
    开启Centos8的SSH服务
    Openwrt与IPTV之二----udpxy
    Openwrt与IPTV之一----igmpproxy
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5203079.html
Copyright © 2011-2022 走看看