博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ2754 SCOI2012day1T2喵星球上的点名(后缀数组)
阅读量:5266 次
发布时间:2019-06-14

本文共 2701 字,大约阅读时间需要 9 分钟。

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

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
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 }

转载于:https://www.cnblogs.com/Lukaluka/p/5086748.html

你可能感兴趣的文章
P1192-台阶问题
查看>>
Java大数——a^b + b^a
查看>>
简单的数据库操作
查看>>
帧的最小长度 CSMA/CD
查看>>
树状数组及其他特别简单的扩展
查看>>
普通求素数和线性筛素数
查看>>
PHP截取中英文混合字符
查看>>
【洛谷P1816 忠诚】线段树
查看>>
电子眼抓拍大解密
查看>>
tomcat7的数据库连接池tomcatjdbc的25个优势
查看>>
Html 小插件5 百度搜索代码2
查看>>
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
查看>>
java 常用命令
查看>>
51nod1076 (边双连通)
查看>>
Linux pipe函数
查看>>
java equals 小记
查看>>
2019春 软件工程实践 助教总结
查看>>
Zerver是一个C#开发的Nginx+PHP+Mysql+memcached+redis绿色集成开发环境
查看>>
java实现哈弗曼树
查看>>
程序的静态链接,动态链接和装载 (补充)
查看>>