zoukankan      html  css  js  c++  java
  • 「luogu2336」[SCOI2012]喵星球上的点名

    把所有串接在一起,用不同的分隔符分隔,

    然后跑后缀数组。。

    对于每个询问串暴力跑出height大于询问串长度的区间统计答案即可。。。。。。。。。。。。。。但是在洛谷上这种做法被卡掉了

    面向数据加个优化水过。

      1 #include<bits/stdc++.h>
      2 #define R register
      3 using namespace std;
      4 const int N=50010,M=100010,T=500010;
      5 int n,m,s,tot,len[M],head[M],qpos[T];
      6 int ans[M],res[N];
      7 int str[T],x[T<<1],y[T<<1],sa[T],rank[T],h[T],height[T],cnt[T],bel[T];
      8 bool qvis[M];
      9 inline int read(){
     10     int x=0,w=1;char c=0;
     11     while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
     12     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
     13     return x*w;
     14 }
     15 inline void build(){
     16     for(R int i=1;i<=tot;i++) cnt[x[i]]++;
     17     for(R int i=1;i<=s;i++) cnt[i]+=cnt[i-1];
     18     for(R int i=tot;i;i--) sa[cnt[x[i]]--]=i;
     19     for(R int i=0;i<=s;i++) cnt[i]=0;
     20     for(R int k=1;k<=tot;k<<=1){
     21         int num=0;
     22         for(R int i=tot;i>tot-k;i--) y[++num]=i;
     23         for(R int i=1;i<=tot;i++) if(sa[i]>k) y[++num]=sa[i]-k;
     24         for(R int i=1;i<=tot;i++) cnt[x[i]]++;
     25         for(R int i=1;i<=s;i++) cnt[i]+=cnt[i-1];
     26         for(R int i=tot;i;i--) sa[cnt[x[y[i]]]--]=y[i];
     27         for(R int i=0;i<=s;i++) cnt[i]=0;
     28         swap(x,y);
     29         x[sa[1]]=num=1;
     30         for(int i=2;i<=tot;i++){
     31             if(y[sa[i]]!=y[sa[i-1]]||y[sa[i]+k]!=y[sa[i-1]+k]) num++;
     32             x[sa[i]]=num;
     33         }
     34         if(num>=tot) break;
     35         s=num;
     36     }
     37     int t=0;
     38     for(R int i=1;i<=tot;i++) rank[sa[i]]=i;
     39     for(R int i=1;i<=tot;i++){
     40         if(t) t--;
     41         while(rank[i]-1&&str[i+t]==str[sa[rank[i]-1]+t]) t++;
     42         h[i]=t,height[rank[i]]=t;
     43     }
     44     return;
     45 }
     46 int vis[N],timer;
     47 vector<int>curq,curstu;
     48 inline void que(int id){
     49     int totq=0,totstu=0,qh=len[id];
     50     timer++;
     51     R int p=rank[head[id]];
     52     curq.push_back(id);totq++;
     53     while(p>=1&&height[p]>=qh){
     54         p--;
     55         if(qpos[p]&&len[qpos[p]]==qh){
     56             curq.push_back(qpos[p]);
     57             totq++;
     58         }
     59         if(bel[sa[p]]&&vis[bel[sa[p]]]!=timer){
     60             vis[bel[sa[p]]]=timer,totstu++;
     61             curstu.push_back(bel[sa[p]]);
     62         }
     63     }
     64     p=rank[head[id]]+1;
     65     while(p<=tot&&height[p]>=qh){
     66         if(qpos[p]&&len[qpos[p]]==qh){
     67             curq.push_back(qpos[p]);
     68             totq++;
     69         }
     70         if(bel[sa[p]]&&vis[bel[sa[p]]]!=timer){
     71             vis[bel[sa[p]]]=timer,totstu++;
     72             curstu.push_back(bel[sa[p]]);
     73         }
     74         p++;
     75     }
     76     for(R int i=0;i<totq;i++) ans[curq[i]]=totstu,qvis[curq[i]]=1;
     77     for(R int i=0;i<totstu;i++) res[curstu[i]]+=totq;
     78     curq.clear();curstu.clear();
     79     return;
     80 }
     81 int main(){
     82     int t1,t2,div=10001;
     83     n=read(),m=read();
     84     for(R int i=1;i<=n;i++){
     85         t1=read();
     86         for(int j=1;j<=t1;j++) t2=read(),str[++tot]=t2,x[tot]=t2,bel[tot]=i;
     87         str[++tot]=++div,x[tot]=div;
     88         t1=read();
     89         for(int j=1;j<=t1;j++) t2=read(),str[++tot]=t2,x[tot]=t2,bel[tot]=i;
     90         str[++tot]=++div,x[tot]=div;
     91     }
     92     for(R int i=1;i<=m;i++){
     93         len[i]=read(),head[i]=tot+1;
     94         for(int j=1;j<=len[i];j++) t2=read(),str[++tot]=t2,x[tot]=t2;
     95         str[++tot]=++div,x[tot]=div;
     96     }
     97     s=div;
     98     build();
     99     for(R int i=1;i<=m;i++) qpos[rank[head[i]]]=i;
    100     for(R int i=1;i<=m;i++) if(!qvis[i]) que(i);
    101     for(R int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    102     for(R int i=1;i<n;i++) printf("%d ",res[i]);
    103     printf("%d",res[n]);
    104     return 0;
    105 }
  • 相关阅读:
    mongoDB的常用语法
    Linux系统清除缓存
    110:类视图讲解
    109:大型CSV文件的处理方式
    108:生成和下载csv文件
    107:JsonResponse用法详解
    106:HttpResponse对象讲解
    104~105:HttpRequest对象讲解和QueryDict的用法讲解
    103:重定向详解
    102:限制请求method装饰器
  • 原文地址:https://www.cnblogs.com/mycups/p/8563640.html
Copyright © 2011-2022 走看看