标签:
后缀数组的板有点问题_(:з」∠)_
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