【HDOJ】3948 The Number of Palindromes
2016-02-04 00:22
381 查看
后缀数组求不重复回文子串数目。注意dp数组。
数据生成器。
/* 3948 */ #include <iostream> #include <sstream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <algorithm> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <climits> #include <cctype> #include <cassert> #include <functional> #include <iterator> #include <iomanip> using namespace std; //#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int> #define stpii set<pair<int, int> > #define mpii map<int,int> #define vi vector<int> #define pii pair<int,int> #define vpii vector<pair<int,int> > #define rep(i, a, n) for (int i=a;i<n;++i) #define per(i, a, n) for (int i=n-1;i>=a;--i) #define clr clear #define pb push_back #define mp make_pair #define fir first #define sec second #define all(x) (x).begin(),(x).end() #define SZ(x) ((int)(x).size()) #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 const int INF = 0x3f3f3f3f; const int maxl = 2e5+5; const int maxn = 4e5+5; char s[maxl], ss[maxl]; int a[maxn]; int height[maxn], rrank[maxn], sa[maxn]; int wa[maxn], wb[maxn], wc[maxn], wv[maxn]; bool visit[maxn]; int dp[19][maxn]; bool 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, *x=wa, *y=wb, *t, p; for (i=0; i<m; ++i) wc[i] = 0; for (i=0; i<n; ++i) wc[x[i]=r[i]]++; for (i=1; i<m; ++i) wc[i] += wc[i-1]; for (i=n-1; i>=0; --i) sa[--wc[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) wc[i] = 0; for (i=0; i<n; ++i) wc[wv[i]]++; for (i=1; i<m; ++i) wc[i] += wc[i-1]; for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i]; for (t=x,x=y,y=t, x[sa[0]]=0, p=1,i=1; i<n; ++i) x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++; } } void calheight(int *r, int *sa, int n) { int i, j, k = 0; for (i=1; i<=n; ++i) rrank[sa[i]] = i; for (i=0; i<n; height[rrank[i++]]=k) for (k?k--:0, j=sa[rrank[i]-1]; r[i+k]==r[j+k]; ++k) ; } void printSa(int n) { for (int i=1; i<=n; ++i) printf("%d ", sa[i]); putchar('\n'); } void printHeight(int n) { for (int i=1; i<=n; ++i) printf("%d ", height[i]); putchar('\n'); } void printRank(int n) { for (int i=1; i<=n; ++i) printf("%d ", rrank[i]); putchar('\n'); } void init_RMQ(int n) { int i, j; for (i=1; i<=n; ++i) dp[0][i] = height[i]; dp[0][1] = INF; for (j=1; (1<<j)<=n; ++j) for (i=1; i+(1<<j)-1<=n; ++i) dp[j][i] = min(dp[j-1][i], dp[j-1][i+(1<<(j-1))]); } int RMQ(int l, int r) { if (l > r) swap(l, r); ++l; int k = 0; while (1<<(k+1) <= r-l+1) ++k; return min(dp[k][l], dp[k][r-(1<<k)+1]); } void solve() { int len = strlen(s); int nn = len * 2 + 1, n, nn2 = nn * 2; int l = 0; rep(i, 0, len) { a[l] = a[nn2-l] = 2; ++l; a[l] = a[nn2-l] = s[i]-'a'+3; ++l; } a[l] = a[nn2-l] = 2; a[nn] = 1; a[nn2+1] = 0; n = nn2 + 1; da(a, sa, n+1, 32); calheight(a, sa, n); #ifndef ONLINE_JUDGE // printSa(n); // printHeight(n); #endif init_RMQ(n); int ans = 0, mn = 0, tmp; memset(visit, false, sizeof(visit)); rep(i, 2, n+1) { mn = min(mn, height[i]); if (visit[nn2-sa[i]]) { tmp = RMQ(rrank[sa[i]], rrank[nn2-sa[i]]); if (tmp > mn) { ans += (tmp - mn) >> 1; mn = tmp; } } else { visit[sa[i]] = true; } } printf("%d\n", ans); } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif int t; scanf("%d", &t); rep(tt, 1, t+1) { scanf("%s", s); printf("Case #%d: ", tt); solve(); } #ifndef ONLINE_JUDGE printf("time = %d.\n", (int)clock()); #endif return 0; }
数据生成器。
from random import randint, shuffle import shutil import string def GenDataIn(): with open("data.in", "w") as fout: t = 20 bound = 10**3 lc = list(string.lowercase) fout.write("%d\n" % (t)) for tt in xrange(t): length = randint(50, 105) line = "" for i in xrange(length): idx = randint(0, 5) line += lc[idx] fout.write("%s\n" % (line)) def MovDataIn(): desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" shutil.copyfile("data.in", desFileName) if __name__ == "__main__": GenDataIn() MovDataIn()
相关文章推荐
- backgroud thread
- dns 报文格式
- 最简单易懂的hash表实现代码
- C语言中的整数自动转换原则
- 第22章 DLL注入和API拦截(1)
- Docker+OpenvSwitch搭建VxLAN实验环境
- 欢迎所以来到我博客的朋友
- Python学习笔记
- 关于“工厂方法”
- Python学习Day01
- 杭电1060 Leftmost Digit
- jython2.7编码问题
- 关闭zsh的auto cd功能
- Python游戏引擎开发(六):动画的小小研究
- Hello Java !
- 最简单的基于FFMPEG的推流器附件:收流器
- uoj#35. 后缀排序 后缀数组
- C#DateTime各种使用
- MarkDown实例代码
- hdu 1525 Euclid's Game 博弈