码迷,mamicode.com
首页 > 编程语言 > 详细

BZOJ2754 SCOI2012day1T2喵星球上的点名(后缀数组)

时间:2015-12-29 21:04:23      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

后缀数组的板有点问题_(:з」∠)_

  1 #include <set>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <iostream>
  7 #include <algorithm>
  8 #define MaxN 30010
  9 #define MaxM 200010
 10 using namespace std;
 11 int n = 0, m, cnt = 0,fen = 10010;
 12 int t[MaxM], t2[MaxM], sa[MaxM], c[MaxM], qwq[MaxM], ch[MaxM], s[MaxM], bel[MaxM], vis[MaxN];
 13 int q[MaxM], sum[MaxN], Q[MaxM];
 14 void get_sa(){
 15     int m = fen+1;
 16     int i, *x = t, *y = t2;
 17     for (i = 0; i < m; i++) c[i] = 0;
 18     for (i = 0; i < n; i++) c[x[i] = s[i]] ++;
 19     for (i = 1; i < m; i++) c[i] += c[i-1];
 20     for (i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
 21     for (int k = 1; k <= n; k <<= 1){
 22         int p = 0;
 23         for (i = n-k; i < n; i++) y[p++] = i;
 24         for (i = 0; i < n; i++) if (sa[i] >= k) y[p++] = sa[i] - k;
 25         for (i = 0; i < m; i++) c[i] = 0;
 26         for (i = 0; i < n; i++) c[x[y[i]]]++;
 27         for (i = 0; i < m; i++) c[i] += c[i-1];
 28         for (i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
 29         swap(x, y);
 30         p = 1; x[sa[0]] = 0;
 31         for (i = 0; i < n; i++)
 32             x[sa[i]] = y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k] ? p-1 : p++;
 33         m = p;
 34     }
 35 }
 36 
 37 void read_s(int a){
 38     int l;
 39     scanf("%d", &l);
 40     for (int i = 1; i <= l; i++) {
 41         bel[n] = a, scanf("%d", &s[n++]);
 42     }
 43     s[n++] = ++fen;
 44 }
 45 
 46 int judge(int *p, int pos, int len) {
 47     int st = sa[pos];
 48     for (int i = 0; i < len; i++) {
 49         if (p[i] < s[i+st]) return 1;
 50         if (p[i] > s[i+st]) return -1;
 51     }
 52     return 0;
 53 }
 54 
 55 int match(int *p, int len)
 56 {
 57     int l = -1, r = n, mid, st = -1, t = 0, en = 0;
 58     while (l + 1 < r){
 59         mid = (l+r) / 2;
 60         int ret = judge(p, mid, len);
 61         if (ret > 0) r = mid; 
 62         else l = mid;
 63     }
 64     en = l;    
 65     l = -1, r = n;
 66     while (l + 1 < r){
 67         mid = (l+r) / 2;
 68         int ret = judge(p, mid, len);
 69         if (ret >= 0) r = mid;
 70         else l = mid;
 71     }    
 72     st = r;
 73     int tot = 0;
 74     for (int i = st; i <= en; i++) {
 75         q[++t] = bel[sa[i]];
 76     }
 77     for (int i = 1; i <= t; i++) {
 78         if (!vis[q[i]]) vis[q[i]] = 1, tot++, sum[q[i]]++;
 79     }
 80     for (int i = 1; i <= t; i++) { vis[q[i]] = 0; }
 81     return tot;
 82 } 
 83 
 84 int Solve(){
 85     int len;
 86     scanf("%d", &len);
 87     for (int i = 0; i < len; i++) scanf("%d", &ch[i]);
 88     return match(ch, len);
 89 }
 90 
 91 void Read_Data(){
 92     int a, b;
 93     scanf("%d%d", &a, &b);
 94     for (int i = 1; i <= a; i++) read_s(i), read_s(i); 
 95     get_sa();
 96     for (int i = 1; i <= b; i++) printf("%d\n", Solve()); 
 97     for (int i = 1; i <= a; i++) {
 98         if (i != a) printf("%d ", sum[i]);
 99         else printf("%d", sum[i]);
100     }
101 }
102 
103 int main(){
104     Read_Data();
105     return 0;
106 }

BZOJ2754 SCOI2012day1T2喵星球上的点名(后缀数组)

标签:

原文地址:http://www.cnblogs.com/Lukaluka/p/5086748.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!