【POJ】1743 Musical Theme
2016-02-02 22:23
323 查看
后缀数组基础题目。
倍增法解。
DC3解。
数据发生器。
倍增法解。
/* 1743 */ #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 maxn = 20005; int a[maxn], b[maxn]; int rank[maxn], sa[maxn], height[maxn]; int wa[maxn], wb[maxn], wv[maxn], wc[maxn]; int n; 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, p, *x=wa, *y=wb, *t; 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, 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++; } } 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) ; } void printSa(int n) { puts("sa ="); rep(i, 1, n+1) printf("%d ", sa[i]); putchar('\n'); } void printHeight(int n) { puts("height ="); rep(i, 1, n+1) printf("%d ", height[i]); putchar('\n'); } bool judge(int bound) { int mx = INT_MIN, mn = INT_MAX; rep(i, 1, n+1) { if (height[i] >= bound) { mx = max(mx, sa[i]); mn = min(mn, sa[i]); if (mx-mn >= bound) return true; } else { mx = mn = sa[i]; } } return false; } void solve() { rep(i, 0, n-1) b[i] = a[i] - a[i+1] + 90; b[n-1] = 0; da(b, sa, n, 200); calheight(b, sa, --n); #ifndef ONLINE_JUDGE // printSa(n); // printHeight(n); #endif int l = 4, r = n, mid; int ans = -1; while (l <= r) { mid = (l + r) >> 1; if (judge(mid)) { ans = mid; l = mid + 1; } else { r = mid - 1; } } printf("%d\n", ans+1); } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif while (scanf("%d", &n)!=EOF && n) { rep(i, 0, n) scanf("%d", &a[i]); solve(); } #ifndef ONLINE_JUDGE printf("time = %d.\n", (int)clock()); #endif return 0; }
DC3解。
/* 1743 */ #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 maxn = 20005; int a[maxn], b[maxn*3]; int rank[maxn], sa[maxn*3], height[maxn]; int wa[maxn], wb[maxn], wv[maxn], wc[maxn]; int n; bool c0(int *r, int a, int b) { return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2]; } bool c12(int k, int *r, int a, int b) { if (k == 2) return r[a]<r[b] || (r[a]==r[b] && c12(1, r, a+1, b+1)); else return r[a]<r[b] || (r[a]==r[b] && wv[a+1]<wv[b+1]); } void sort(int *r, int *a, int *b, int n, int m) { int i; for (i=0; i<n; ++i) wv[i] = r[a[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) b[--wc[wv[i]]] = a[i]; } #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb)) #define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2) void dc3(int *r, int* sa, int n, int m) { int i, j, *rn = r + n, *san = sa + n; int ta = 0, tb = (n + 1) / 3, tbc = 0, p; r = r[n+1] = 0; for (i=0; i<n; ++i) if (i%3!=0) wa[tbc++] = i; sort(r+2, wa, wb, tbc, m); sort(r+1, wb, wa, tbc, m); sort(r, wa, wb, tbc, m); for (p=1, rn[F(wb[0])]=0, i=1; i<tbc; ++i) rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p-1:p++; if (p < tbc) dc3(rn, san, tbc, p); else for (i=0; i<tbc; ++i) san[rn[i]] = i; for (i=0; i<tbc; ++i) if (san[i] < tb) wb[ta++] = san[i] * 3; if (n%3 == 1) wb[ta++] = n-1; sort(r, wb, wa, ta, m); for (i=0; i<tbc; ++i) wv[wb[i]=G(san[i])]=i; for (i=0,j=0,p=0; i<ta&&j<tbc; ++p) sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++]; while (i < ta) sa[p++] = wa[i++]; while (j < tbc) sa[p++] = wb[j++]; } 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) ; } void printSa(int n) { puts("sa ="); rep(i, 1, n+1) printf("%d ", sa[i]); putchar('\n'); } void printHeight(int n) { puts("height ="); rep(i, 1, n+1) printf("%d ", height[i]); putchar('\n'); } bool judge(int bound) { int mx = INT_MIN, mn = INT_MAX; rep(i, 1, n+1) { if (height[i] >= bound) { mx = max(mx, sa[i]); mn = min(mn, sa[i]); if (mx-mn >= bound) return true; } else { mx = mn = sa[i]; } } return false; } void solve() { rep(i, 0, n-1) b[i] = a[i] - a[i+1] + 90; b[n-1] = 0; dc3(b, sa, n, 200); calheight(b, sa, --n); #ifndef ONLINE_JUDGE printSa(n); printHeight(n); #endif int l = 4, r = n, mid; int ans = -1; while (l <= r) { mid = (l + r) >> 1; if (judge(mid)) { ans = mid; l = mid + 1; } else { r = mid - 1; } } printf("%d\n", ans+1); } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif while (scanf("%d", &n)!=EOF && n) { rep(i, 0, n) scanf("%d", &a[i]); 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 = 88 for tt in xrange(t): n = randint(1000, 5000) fout.write("%d\n" % (n)) dataList = [] for i in xrange(n): x = randint(1, bound) dataList.append(x) fout.write(" ".join(map(str, dataList)) + "\n") fout.write("0\n") def MovDataIn(): desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" shutil.copyfile("data.in", desFileName) if __name__ == "__main__": GenDataIn() MovDataIn()
相关文章推荐
- 个人笔记 html 04 提交表单与跳转页面冲突时
- HDOJ 1385 Minimum Transport Cost (Floyd + 打印字典序最小的路径)
- AngularJS中实现Model缓存
- ActiveMQ之消息指针
- CDOJ 1270 Playfair
- c++中的数据类型
- C++ 通用编程
- 后PPT时代
- CentOS下安装python-mysqldb
- 第二章实例:SimpleAdapter结合listview实现列表视图
- 搜索与回溯练习(二)
- 第三百零六天 how can I 坚持
- CDOJ 1271 Search gold
- 网络流 最大流 ISAP算法
- java数据库编程——执行SQL 语句
- 331. Verify Preorder Serialization of a Binary Tree
- 网络流 ISAP算法
- 军旅风电商崛起:砺剑户外用品深度调查
- CodeForces 543B Destroying Roads(最短路BFS)
- ruby include和exclude区别