【POJ】1743 Musical Theme

后缀数组基础题目。
倍增法解。

  1 /* 1743 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 
 43 const int maxn = 20005;
 44 int a[maxn], b[maxn];
 45 int rank[maxn], sa[maxn], height[maxn];
 46 int wa[maxn], wb[maxn], wv[maxn], wc[maxn];
 47 int n;
 48 
 49 bool cmp(int *r, int a, int b, int l) {
 50     return r[a]==r[b] && r[a+l]==r[b+l];
 51 }
 52 
 53 void da(int *r, int* sa, int n, int m) {
 54     int i, j, p, *x=wa, *y=wb, *t;
 55     
 56     for (i=0; i<m; ++i) wc[i] = 0;
 57     for (i=0; i<n; ++i) wc[x[i]=r[i]]++;
 58     for (i=1; i<m; ++i) wc[i] += wc[i-1];
 59     for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i;
 60     for (j=1,p=1; p<n; j*=2, m=p) {
 61         for (p=0,i=n-j; i<n; ++i) y[p++] = i;
 62         for (i=0; i<n; ++i) if (sa[i]>=j) y[p++] = sa[i]-j;
 63         for (i=0; i<n; ++i) wv[i] = x[y[i]];
 64         for (i=0; i<m; ++i) wc[i] = 0;
 65         for (i=0; i<n; ++i) wc[wv[i]]++;
 66         for (i=1; i<m; ++i) wc[i] += wc[i-1];
 67         for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i];
 68         for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i<n; ++i)
 69             x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++;
 70     }
 71 }
 72 
 73 void calheight(int *r, int* sa, int n) {
 74     int i, j, k = 0;
 75     
 76     for (i=1; i<=n; ++i) rank[sa[i]] = i;
 77     for (i=0; i<n; height[rank[i++]]=k)
 78     for (k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k) ;
 79 }
 80 
 81 void printSa(int n) {
 82     puts("sa =");
 83     rep(i, 1, n+1)
 84         printf("%d ", sa[i]);
 85     putchar('\n');
 86 }
 87 
 88 void printHeight(int n) {
 89     puts("height =");
 90     rep(i, 1, n+1)
 91         printf("%d ", height[i]);
 92     putchar('\n');
 93 }
 94 
 95 bool judge(int bound) {
 96     int mx = INT_MIN, mn = INT_MAX;
 97     
 98     rep(i, 1, n+1) {
 99         if (height[i] >= bound) {
100             mx = max(mx, sa[i]);
101             mn = min(mn, sa[i]);
102             if (mx-mn >= bound)
103                 return true;
104         } else {
105             mx = mn = sa[i];
106         }
107     }
108     
109     return false;
110 }
111 
112 void solve() {
113     rep(i, 0, n-1)
114         b[i] = a[i] - a[i+1] + 90;
115     b[n-1] = 0;
116     da(b, sa, n, 200);
117     calheight(b, sa, --n);
118     
119     #ifndef ONLINE_JUDGE
120         // printSa(n);
121         // printHeight(n);
122     #endif
123     
124     int l = 4, r = n, mid;
125     int ans = -1;
126     
127     while (l <= r) {
128         mid = (l + r) >> 1;
129         if (judge(mid)) {
130             ans = mid;
131             l = mid + 1;
132         } else {
133             r = mid - 1;
134         }
135     }
136     
137     printf("%d\n", ans+1);
138 }
139 
140 int main() {
141     ios::sync_with_stdio(false);
142     #ifndef ONLINE_JUDGE
143         freopen("data.in", "r", stdin);
144         freopen("data.out", "w", stdout);
145     #endif
146     
147     while (scanf("%d", &n)!=EOF && n) {
148         rep(i, 0, n)
149             scanf("%d", &a[i]);
150         solve();
151     }
152     
153     #ifndef ONLINE_JUDGE
154         printf("time = %d.\n", (int)clock());
155     #endif
156     
157     return 0;
158 }

DC3解。

  1 /* 1743 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 
 43 const int maxn = 20005;
 44 int a[maxn], b[maxn*3];
 45 int rank[maxn], sa[maxn*3], height[maxn];
 46 int wa[maxn], wb[maxn], wv[maxn], wc[maxn];
 47 int n;
 48 
 49 bool c0(int *r, int a, int b) {
 50     return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2];
 51 }
 52 
 53 bool c12(int k, int *r, int a, int b) {
 54     if (k == 2)
 55         return r[a]<r[b] || (r[a]==r[b] && c12(1, r, a+1, b+1));
 56     else
 57         return r[a]<r[b] || (r[a]==r[b] && wv[a+1]<wv[b+1]);
 58 }
 59 
 60 void sort(int *r, int *a, int *b, int n, int m) {
 61     int i;
 62     
 63     for (i=0; i<n; ++i) wv[i] = r[a[i]];
 64     for (i=0; i<m; ++i) wc[i] = 0;
 65     for (i=0; i<n; ++i) wc[wv[i]]++;
 66     for (i=1; i<m; ++i) wc[i] += wc[i-1];
 67     for (i=n-1; i>=0; --i) b[--wc[wv[i]]] = a[i];
 68 }
 69 
 70 #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb))
 71 #define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2)
 72 void dc3(int *r, int* sa, int n, int m) {
 73     int i, j, *rn = r + n, *san = sa + n;
 74     int ta = 0, tb = (n + 1) / 3, tbc = 0, p;
 75     
 76     r[n] = r[n+1] = 0;
 77     for (i=0; i<n; ++i) if (i%3!=0) wa[tbc++] = i;
 78     sort(r+2, wa, wb, tbc, m);
 79     sort(r+1, wb, wa, tbc, m);
 80     sort(r, wa, wb, tbc, m);
 81     for (p=1, rn[F(wb[0])]=0, i=1; i<tbc; ++i)
 82         rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p-1:p++;
 83     if (p < tbc)
 84         dc3(rn, san, tbc, p);
 85     else
 86         for (i=0; i<tbc; ++i) san[rn[i]] = i;
 87     for (i=0; i<tbc; ++i)
 88         if (san[i] < tb)
 89             wb[ta++] = san[i] * 3;
 90     if (n%3 == 1)
 91         wb[ta++] = n-1;
 92     sort(r, wb, wa, ta, m);
 93     for (i=0; i<tbc; ++i) wv[wb[i]=G(san[i])]=i;
 94     for (i=0,j=0,p=0; i<ta&&j<tbc; ++p)
 95         sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
 96     while (i < ta) sa[p++] = wa[i++];
 97     while (j < tbc) sa[p++] = wb[j++];
 98 }
 99 
100 void calheight(int *r, int* sa, int n) {
101     int i, j, k = 0;
102     
103     for (i=1; i<=n; ++i) rank[sa[i]] = i;
104     for (i=0; i<n; height[rank[i++]]=k)
105     for (k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k) ;
106 }
107 
108 void printSa(int n) {
109     puts("sa =");
110     rep(i, 1, n+1)
111         printf("%d ", sa[i]);
112     putchar('\n');
113 }
114 
115 void printHeight(int n) {
116     puts("height =");
117     rep(i, 1, n+1)
118         printf("%d ", height[i]);
119     putchar('\n');
120 }
121 
122 bool judge(int bound) {
123     int mx = INT_MIN, mn = INT_MAX;
124     
125     rep(i, 1, n+1) {
126         if (height[i] >= bound) {
127             mx = max(mx, sa[i]);
128             mn = min(mn, sa[i]);
129             if (mx-mn >= bound)
130                 return true;
131         } else {
132             mx = mn = sa[i];
133         }
134     }
135     
136     return false;
137 }
138 
139 void solve() {
140     rep(i, 0, n-1)
141         b[i] = a[i] - a[i+1] + 90;
142     b[n-1] = 0;
143     dc3(b, sa, n, 200);
144     calheight(b, sa, --n);
145     
146     #ifndef ONLINE_JUDGE
147         printSa(n);
148         printHeight(n);
149     #endif
150     
151     int l = 4, r = n, mid;
152     int ans = -1;
153     
154     while (l <= r) {
155         mid = (l + r) >> 1;
156         if (judge(mid)) {
157             ans = mid;
158             l = mid + 1;
159         } else {
160             r = mid - 1;
161         }
162     }
163     
164     printf("%d\n", ans+1);
165 }
166 
167 int main() {
168     ios::sync_with_stdio(false);
169     #ifndef ONLINE_JUDGE
170         freopen("data.in", "r", stdin);
171         freopen("data.out", "w", stdout);
172     #endif
173     
174     while (scanf("%d", &n)!=EOF && n) {
175         rep(i, 0, n)
176             scanf("%d", &a[i]);
177         solve();
178     }
179     
180     #ifndef ONLINE_JUDGE
181         printf("time = %d.\n", (int)clock());
182     #endif
183     
184     return 0;
185 }

数据发生器。

 1 from random import randint, shuffle
 2 import shutil
 3 import string
 4 
 5 
 6 def GenDataIn():
 7     with open("data.in", "w") as fout:
 8         t = 20
 9         bound = 88
10         for tt in xrange(t):
11             n = randint(1000, 5000)
12             fout.write("%d\n" % (n))
13             dataList = []
14             for i in xrange(n):
15                 x = randint(1, bound)
16                 dataList.append(x)    
17             fout.write(" ".join(map(str, dataList)) + "\n")
18         fout.write("0\n")
19         
20                 
21 def MovDataIn():
22     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
23     shutil.copyfile("data.in", desFileName)
24 
25     
26 if __name__ == "__main__":
27     GenDataIn()
28     MovDataIn()

 

你可能感兴趣的:(【POJ】1743 Musical Theme)