【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()
时间: 2024-08-10 21:28:10

【HDOJ】4029 Distinct Sub-matrix的相关文章

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)

【HDOJ】1686 Oulipo

kmp算法. 1 #include <cstdio> 2 #include <cstring> 3 4 char src[10005], des[1000005]; 5 int next[10005], total; 6 7 void kmp(char des[], char src[]){ 8 int ld = strlen(des); 9 int ls = strlen(src); 10 int i, j; 11 12 total = i = j = 0; 13 while (

【HDOJ】2795 Billboard

线段树.注意h范围(小于等于n). 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 200005 5 #define lson l, mid, rt<<1 6 #define rson mid+1, r, rt<<1|1 7 #define mymax(x, y) (x>y) ? x:y 8 9 int nums[MAXN<<2]; 10 int h, w; 11 12