ACM Templates added.

This commit is contained in:
unknown 2016-08-13 23:36:53 +08:00
parent 6fc89586ec
commit e254c2bb97
4 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,13 @@
inline int Manacher(int a[], int n, int ret[]) {
int MaxR = -1, where = 0, Ans = 0;
for (int i = 1; i <= n; i++) {
int &it = ret[i]; it = 0;
if (i <= MaxR) it = min(ret[where * 2 - i], MaxR - i);
while (i - it - 1 >= 1 && i + it + 1 <= n && a[i - it - 1] == a[i + it + 1]) it++;
if (it + i > MaxR) MaxR = it + i, where = i;
int tmp = (it << 1) + 1; tmp >>= 1;
if (a[i - it] != '$') tmp++; //如果a[i - it]不是分割符
Ans = max(Ans, tmp);
}
return Ans;
}

View File

@ -0,0 +1 @@
Manacher算法求最长的回文半径, 注意原字符串的偶数位置要加占位字符(比如abc变为a$b$c), 返回其最长回文子串的长度。

View File

@ -0,0 +1,71 @@
const long double eps = 1e-9;
const int MAXN = 10100; // 最大约束个数
const int MAXM = 1010; // 最大变量个数
const long double inf = 1e100;
int next[MAXM]; long double a[MAXN][MAXM], b[MAXM];
int where[MAXM + MAXN]; // where[i] 表示原来第 i 个变量现在在哪个位置
int pos[MAXM + MAXN]; // pos[i] 表示第 i 个位置现在是哪个变量
int n, m;
void pivot(int r, int c) {
int &x = pos[r + m], &y = pos[c];
swap(where[x], where[y]); swap(x, y);
long double t = -a[r][c]; a[r][c] = -1;
int last = MAXM - 1;
for (int i = 0; i <= m; i++) {
a[r][i] /= t;
if (fabs(a[r][i]) > eps) next[last] = i, last = i;
}
next[last] = -1;
for (int i = 0; i <= n; i++) if (i != r && fabs(a[i][c]) > eps) {
t = a[i][c], a[i][c] = 0;
for (int j = next[MAXM - 1]; j != -1; j = next[j])
a[i][j] += a[r][j] * t;
}
}
long double get(void) {
long double best, t; int r, c;
for (;;) {
r = c = -1, best = -inf;
for (int i = 1; i <= m; i++) if (a[0][i] > eps) {c = i; break;}
if (c == -1) return a[0][0]; // 从这里返回表示找到了最优解
for (int i = 1; i <= n; i++) if (a[i][c] < -eps && (t = a[i][0] / a[i][c]) > best) best = t, r = i;
if (r == -1) return inf; // 从这里返回表示最优解为inf
pivot(r, c);
}
}
int init(void) {
for (int i = 1; i <= m + n + 1; i++) where[i] = i, pos[i] = i;
long double best = -eps, r = 0;
for (int i = 1; i <= n; i++) if (a[i][0] < best) best = a[i][0], r = i;
if (!r) return 1;
for (int i = 0; i <= m; i++) b[i] = a[0][i], a[0][i] = 0; a[0][m + 1] = -1;
for (int i = 1; i <= n; i++) a[i][m + 1] = 1; m++;
pivot(r, m);
long double tmp = get();
if (tmp < -eps) return 0; else {
if (where[m] > m) {
for (int i = 1; i <= m; i++) if (fabs(a[where[m] - m][i]) > eps) {
pivot(where[m] - m, i);
break;
}
}
for (int i = 0; i <= n; i++) a[i][where[m]] = 0;
for (int i = 0; i <= m; i++) a[0][i] = 0; a[0][0] = b[0];
for (int i = 1; i <= m; i++) if (where[i] > m) {
int t = where[i] - m;
for (int j = 0; j <= m; j++) a[0][j] += b[i] * a[t][j];
} else a[0][where[i]] += b[i];
return 1;
}
}
long double process(void) {
if (!init()) return -inf;
return get();
}

View File

@ -0,0 +1,4 @@
n个约束m个变量。
process 返回值为-inf表示无解inf表示无穷解否则表示最优解。
矩阵a[0][1\dots m]表示目标函数的系数。举例线性规划:
$\max(-2x -3y - 4z)$, 其中$3x + 2y + z \le 10, 2x + 5y + 3z \le 15$. 数组a应为: \{\{0,-2,-3,-4\},\{10,-3,-2,-1\},\{15,-2,-5,-3\}\}.