【HDOJ】4029 Distinct Sub-matrix

思路是枚举矩阵列数,然后将字符矩阵转换成字符串,通过字符数组求不同子串数目。最后,减去不成立的情况。使用特殊字符分割可能的组合。

  1 /* 4029 */
  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 maxr = 130;
 44 const int maxn = 2e5+5;
 45 const int base = 10007;
 46 map<int,int> tb;
 47 int a[maxn*3];
 48 int height[maxn], rrank[maxn], sa[maxn*3];
 49 int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
 50 char s[maxr][maxr];
 51 int H[maxr][maxr];
 52 int r, c;
 53 
 54 bool c0(int *r, int a, int b) {
 55     return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2];
 56 }
 57 
 58 bool c12(int k, int *r, int a, int b) {
 59     if (k == 2)
 60         return r[a]<r[b] || (r[a]==r[b] && c12(1, r, a+1, b+1));
 61     else
 62         return r[a]<r[b] || (r[a]==r[b] && wv[a+1]<wv[b+1]);
 63 }
 64 
 65 void sort(int *r, int *a, int *b, int n, int m) {
 66     int i;
 67     
 68     for (i=0; i<n; ++i) wv[i] = r[a[i]];
 69     for (i=0; i<m; ++i) wc[i] = 0;
 70     for (i=0; i<n; ++i) wc[wv[i]]++;
 71     for (i=1; i<m; ++i) wc[i] += wc[i-1];
 72     for (i=n-1; i>=0; --i) b[--wc[wv[i]]] = a[i];
 73 }
 74 
 75 #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb))
 76 #define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2)
 77 void dc3(int *r, int *sa, int n, int m) {
 78     int i, j, *rn=r+n, *san=sa+n, ta=0, tb=(n+1)/3, tbc=0, p;
 79     
 80     r[n] = r[n+1] = 0;
 81     for (i=0; i<n; ++i) if (i%3!=0) wa[tbc++] = i;
 82     sort(r+2, wa, wb, tbc, m);
 83     sort(r+1, wb, wa, tbc, m);
 84     sort(r, wa, wb, tbc, m);
 85     for (p=1, rn[F(wb[0])]=0, i=1; i<tbc; ++i)
 86         rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p-1 : p++;
 87     if (p < tbc)
 88         dc3(rn, san, tbc, p);
 89     else
 90         for (i=0; i<tbc; ++i) san[rn[i]] = i;
 91     for (i=0; i<tbc; ++i)
 92         if (san[i] < tb)
 93             wb[ta++] = san[i] * 3;
 94     if (n%3 == 1)
 95         wb[ta++] = n - 1;
 96     sort(r, wb, wa, ta, m);
 97     for (i=0; i<tbc; ++i) wv[wb[i]=G(san[i])] = i;
 98     for (i=0,j=0,p=0; i<ta && j<tbc; ++p)
 99         sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
100     while (i < ta) sa[p++] = wa[i++];
101     while (j < tbc) sa[p++] = wb[j++];
102 }
103 
104 void calheight(int *r, int *sa, int n) {
105     int i, j, k = 0;
106     
107     for (i=1; i<=n; ++i) rrank[sa[i]] = i;
108     for (i=0; i<n; height[rrank[i++]]=k)
109     for (k?k--:0, j=sa[rrank[i]-1]; r[j+k]==r[i+k]; ++k) ;
110 }
111 
112 void printSa(int n) {
113     for (int i=1; i<=n; ++i)
114         printf("%d ", sa[i]);
115     putchar('\n');
116 }
117 
118 void printHeight(int n) {
119     for (int i=1; i<=n; ++i)
120         printf("%d ", height[i]);
121     putchar('\n');
122 }
123 
124 void solve() {
125     __int64 ans = 0, tot, tmp;
126     int n = 0;
127     
128     memset(H, 0, sizeof(H));
129     rep(w, 1, c+1) {
130         tb.clr();
131         int cn = c - w + 1;
132         int cnt = cn + 1;
133         int sidx = 1;
134         
135         rep(i, 0, r) {
136             rep(j, 0, cn) {
137                 H[i][j] = H[i][j] * base + s[i][j+w-1]-'A';
138                 if (tb.find(H[i][j]) == tb.end())
139                     tb[H[i][j]] = cnt++;
140             }
141         }
142         
143         n = 0;
144         rep(j, 0, cn) {
145             rep(i, 0, r)
146                 a[n++] = tb[H[i][j]];
147             a[n++] = sidx++;
148         }
149         a[n] = 0;
150         
151         dc3(a, sa, n+1, cnt+5);
152         calheight(a, sa, n);
153         
154         tot = 0;
155         rep(i, 1, n+1)
156             tot += (n - sa[i] - height[i]);
157         
158         tmp = n;
159         rep(i, 0, cn) {
160             tmp -= r;
161             tot -= (r+1) * tmp;
162             --tmp;
163         }
164         
165         ans += tot;
166     }
167     
168     printf("%I64d\n", ans);
169 }
170 
171 int main() {
172     ios::sync_with_stdio(false);
173     #ifndef ONLINE_JUDGE
174         freopen("data.in", "r", stdin);
175         freopen("data.out", "w", stdout);
176     #endif
177     
178     int t;
179     
180     scanf("%d", &t);
181     rep(tt, 1, t+1) {
182         scanf("%d %d", &r, &c);
183         rep(i, 0, r)
184             scanf("%s", s[i]);
185         printf("Case #%d: ", tt);
186         solve();
187     }
188     
189     #ifndef ONLINE_JUDGE
190         printf("time = %d.\n", (int)clock());
191     #endif
192     
193     return 0;
194 }

数据生成器。

 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         uc = list(string.uppercase)
10         fout.write("%d\n" % (t))
11         for tt in xrange(t):
12             n = randint(20, 50)
13             m = randint(20, 50)
14             fout.write("%d %d\n" % (n, m))
15             for i in xrange(n):
16                 line = ""
17                 for j in xrange(m):
18                     idx = randint(0, 25)
19                     line += uc[idx]
20                 fout.write("%s\n" % (line))
21                 
22                 
23 def MovDataIn():
24     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
25     shutil.copyfile("data.in", desFileName)
26 
27     
28 if __name__ == "__main__":
29     GenDataIn()
30     MovDataIn()

 

posted on 2016-02-04 12:29  Bombe  阅读(195)  评论(0编辑  收藏  举报

导航