日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看

發布時間:2023/12/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SPOJ.com - Problem SUBLEX

  這么裸的一個SAM,放在了死破OJ上面就是個坑。

注意用SAM做的時候輸出要用一個數組存下來,然后再puts,不然一個一個字符輸出會更慢。

還有一個就是不要多數據輸入,估計最后多了幾個沒用的數字,反正我這么做一直無端端的RE。(就這樣浪費了我一天好么!出數據的人這么不負責!)

最后就是,第k大的k是會超過子串數的。(這什么腦殘配置?)

  綜上,這題除了坑就是坑。

?

代碼如下:

?

1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 222222; 5 const int LAST = 90000; 6 const int K = 26; 7 8 struct Node { 9 Node *nx[K], *fail; 10 int dist; 11 long long sub; 12 13 void Clear(const int d = 0) { 14 memset(nx, 0, sizeof nx); 15 fail = 0; 16 dist = d; 17 sub = 0; 18 } 19 } ; 20 21 struct SAM { 22 Node node[N << 1]; 23 Node *root, *last; 24 int ttNode; 25 26 Node *Mem(const int d = 0) { 27 Node *temp = node + ttNode++; 28 29 temp->Clear(d); 30 31 return temp; 32 } 33 34 void Clear() { 35 ttNode = 0; 36 root = last = Mem(); 37 } 38 39 void Expand(const char c) { 40 const int idx = c - 'a'; 41 Node *p = last, *np = Mem(p->dist + 1); 42 43 for ( ; p && p->nx[idx] == 0; p = p->fail) { 44 p->nx[idx] = np; 45 } 46 if (p) { 47 Node *q = p->nx[idx]; 48 49 if (p->dist + 1 != q->dist) { 50 Node *nq = Mem(); 51 52 *nq = *q; 53 nq->dist = p->dist + 1; 54 q->fail = np->fail = nq; 55 for ( ; p && p->nx[idx] == q; p = p->fail) { 56 p->nx[idx] = nq; 57 } 58 } else { 59 np->fail = q; 60 } 61 } else { 62 np->fail = root; 63 } 64 last = np; 65 } 66 67 int dist[N << 1]; 68 Node *ptr[N << 1]; 69 70 void GetSub() { 71 memset(dist, 0, sizeof dist); 72 for (int i = 0; i < ttNode; ++i) { 73 ++dist[node[i].dist]; 74 } 75 for (int i = 1; i < ttNode; ++i) { 76 dist[i] += dist[i - 1]; 77 } 78 for (int i = 0; i < ttNode; ++i) { 79 ptr[--dist[node[i].dist]] = node + i; 80 } 81 for (int i = ttNode - 1; i >= 0; --i) { 82 Node *p = ptr[i]; 83 84 p->sub = 1; 85 for (int j = 0; j < K; ++j) { 86 if (p->nx[j]) { 87 p->sub += p->nx[j]->sub; 88 } 89 } 90 } 91 --node[0].sub; 92 //for (int i = 0; i < ttNode; ++i) { cout << node[i].dist << ' '; } cout << endl; 93 //for (int i = 0; i < ttNode; ++i) { cout << node[i].sub << ' '; } cout << endl; 94 //for (int i = 0; i < ttNode; ++i) { cout << i << ": "; for (int j = 0; j < K; ++j) { cout << (node[i].nx[j] ? node[i].nx[j] - node : -1) << ' '; } cout << endl; } 95 } 96 } sam; 97 98 char s[N], answer[N]; 99 100 void Generate(char *const s) { 101 srand(time(0)); 102 for (int i = 0; i < LAST; ++i) { 103 s[i] = rand() % 26 + 'a'; 104 } 105 s[LAST] = 0; 106 } 107 108 int Run() { 109 //while (~scanf("%s", s)) { 110 //while (1) { 111 //Generate(s); 112 scanf("%s", s); 113 sam.Clear(); 114 for (int i = 0; s[i]; ++i) { 115 sam.Expand(s[i]); 116 } 117 sam.GetSub(); 118 //cout << sam.root->sub << endl; 119 //if (sam.ttNode >= (N << 1)) { puts("???"); while (1) ; } 120 121 int n, k; 122 123 scanf("%d", &n); 124 while (n--) { 125 Node *p = sam.root; 126 int pos = 0; 127 128 scanf("%d", &k); 129 //if (k > sam.root->sub) { puts("..."); while (1) ; } 130 k = (k - 1) % sam.root->sub + 1; 131 while (k > 0) { 132 for (int i = 0; i < K; ++i) { 133 if (p->nx[i] == 0) { 134 continue; 135 } 136 137 const int cnt = p->nx[i]->sub; 138 139 if (cnt >= k) { 140 //putchar('a' + i); 141 answer[pos++] = 'a' + i; 142 p = p->nx[i]; 143 --k; 144 break; 145 } else { 146 k -= cnt; 147 } 148 } 149 } 150 answer[pos] = 0; 151 puts(answer); 152 //puts(""); 153 } 154 //} 155 156 return 0; 157 } 158 159 int main() { 160 //ios::sync_with_stdio(0); 161 return Run(); 162 } View Code

?

UPD:還有更坑的,我開99999 * 2的SAM節點數是會TLE的,開222222 * 2才AC。我猜肯定是新增的數據各種問題,數據不在范圍內了。

?

——written by LyonLys

轉載于:https://www.cnblogs.com/LyonLys/p/spoj_sublex.html

總結

以上是生活随笔為你收集整理的spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。