後綴數組的簡單應用
推薦羅穗騫的論文,我的主要代碼也是按照論文上來的。
兩個題基本一樣可以用同樣的代碼通過
代碼如下:
/* * File: main.cpp * Author: liuwei * * Created on October 14, 2010, 7:30 PM */ #include <cstdlib> #include <cstdio> #include <iostream> #include <cstring> using namespace std; #define MAXN 200010 char str[100010]; int arr[MAXN]; int wa[MAXN], wb[MAXN], wv[MAXN], tmp[MAXN]; int sa[MAXN]; //index range 1~n value range 0~n-1 int cmp(int *r, int a, int b, int l) { return r[a] == r[b] && r[a + l] == r[b + l]; } void da(int *r, int *sa, int n, int m) { int i, j, p, *x = wa, *y = wb, *ws = tmp; for (i = 0; i < m; ++i) ws[i] = 0; for (i = 0; i < n; ++i) ws[x[i] = r[i]]++; for (i = 1; i < m; ++i) ws[i] += ws[i - 1]; for (i = n - 1; i >= 0; --i) sa[--ws[x[i]]] = i; for (j = 1, p = 1; p < n; j *= 2, m = p) { for (p = 0, i = n - j; i < n; ++i) y[p++] = i; for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j; for (i = 0; i < n; ++i) wv[i] = x[y[i]]; for (i = 0; i < m; ++i) ws[i] = 0; for (i = 0; i < n; ++i) ws[wv[i]]++; for (i = 1; i < m; ++i) ws[i] += ws[i - 1]; for (i = n - 1; i >= 0; --i) sa[--ws[wv[i]]] = y[i]; for (swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i) x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++; } return; } int rank[MAXN]; //index range 0~n-1 value range 1~n int height[MAXN]; //index from 1 (height[1] = 0) void calHeight(int *r, int *sa, int n) { int i, j, k = 0; for (i = 1; i <= n; ++i) rank[sa[i]] = i; for (i = 0; i < n; height[rank[i++]] = k) for (k ? k-- : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; ++k); return; } int main(int argc, char** argv) { while (EOF != scanf("%s", str)) { int p, n = 0; int len = strlen(str); p = len; for (n = 0; n < len; ++n) arr[n] = str[n] - 96; arr[n++] = 27; scanf("%s", str); len = strlen(str); int i; for (i = 0; i < len; ++i, ++n) arr[n] = str[i] - 96; arr[n] = 0; da(arr, sa, n + 1, 28); calHeight(arr, sa, n); int ret(0); for (i = 2; i <= n; ++i) { if ((sa[i] > p && sa[i - 1] < p) || (sa[i] < p && sa[i - 1] > p)) ret = max(ret, height[i]); } printf("%d/n", ret); } return 0; }
數數 時間限制:3000 ms | 內存限制:65535 KB 難度:2 描述 我們平時數數都是喜歡從左向右數的,但是我們的小白同學最近聽說德國人數數和我們有些不同,他們正好和我們相反,是從右向左數的。因此當他看到123時
A problem is easy 時間限制:1000 ms | 內存限制:65535 KB 難度:3 描述 When Teddy was a child , he was always thinking about s
很早的題,今天終於AC了。 分黑白兩種情況枚舉第一行,與Fliptile類似。 #include <iostream> #include <cstdio> #include <cstring> #define min(a,b)
HDU6354 Everything Has Changed 多校第五場 幾何題 愛德華是鋁循環機械的工人。他的工作是操作機械臂來切割設計模型。以下是他的工作簡介。 假設操作平面爲二維座標系。首先,有一個帶中心座標的圓盤(0 ,
題目描述: 給出圖中一些點的連通關係,判斷任意圖中兩個點是否能從u到v或者v到u。 大致思路: 思路還是先用強連通縮點,之後對於這個圖進行拓撲排序,如果在排序過程中出現並列搜索的點了,也就是說這個子圖中有多個起點,也就是說一定存在(u,v
C++STL泛型編程 ANSI C++中包含了一個C++ STL(Standard Template Library),即C++標準模板庫,又稱C++泛型庫,它在std命名空間中定義了常 用的數據結構和算法,使用起來很方便。 STL提供三
http://codeforces.com/contest/196/problem/B B. Infinite Maze time limit per test 2 seconds memory limit per test
題意:給出一些城市的座標,每個信號基站可以覆蓋兩個相鄰的點,問最少要建多少個基站。 思路:我們要儘可能多的建立能覆蓋兩個城市的基站(二分匹配最大匹配),剩下的城市每個城市建立一個基站。先求出最大匹 配數k。n
題意:有N只奶牛,奶牛有自己認爲最受歡迎的奶牛。奶牛們的這種“認爲”是單向可傳遞的,當A認爲B最受歡迎(B不一定認爲A最受歡迎),且B認爲C最受歡迎時,A一定也認爲C最受歡迎。現在給出M對這樣的“認爲...”的關係,問有多少隻奶牛被除其本
題意:有n個人每個人可以把謠言傳給一些人,傳給每個人有一定的時間,求出你把謠言傳給誰,讓所有的人都知道的時間最短。 思路:枚舉每個點爲起點,到所有點的距離的最大值就是該點爲起點所消耗的時間,求出最小值就可以了,因爲給的n較小,直接
題意:給出n個卡車,每個卡車的類型是七個字符組成的,一種卡車可以從另一種卡車派生來的,代價是兩種卡車間類型不同字符的個數,求出這n中卡車派生的最小代價,n種車有一 種是開始就有的,n-1種是派生出來的。 思路:因爲剛開始有一種卡車,所以就
題意:給出n個字母的一些大小關係,判斷能否拓撲排序或者出現了矛盾,如果是這兩種情況要求出到第幾組關係時就可以得到。否 則就是所給數據不完全。 思路:每讀一組關係進行一次拓撲排序,如果排序成功或者出現矛盾記錄第幾組關係
最近在做最短路徑的題目,有幾道題是同一個類型的,題意基本都是尋找從A到B所有路徑中,路徑的最大邊的最小值。這樣類型的題有POJ - 2253 Frogger, UVA - 10048 Audiophobia,POJ - 1797
POJ2386 Lake Counting 和 2018年藍橋杯I題 全球變暖 都屬於深搜的同一種類型的題,都與計數有關,比較有共同點和舉一反三的感覺所以放在一起討論一下。 POJ2386 Lake Counting 題目大意:
題目鏈接 題目大意就是給每個牛的Si和Fi,要你選出一些牛使他們的Si和Fi的總和最大,並且他們的Si的總和不爲0,Fi也是一樣。 一開始看確實不好想,後來看了別人才知道,把Si看成花費,Fi看成價值。 不就是我們熟悉的01揹包