0% found this document useful (0 votes)
8 views

tml

Uploaded by

minhquanp07
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

tml

Uploaded by

minhquanp07
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

suffixArr

struct suffixArray {
vector <int> sa;
vector <int> pos;
vector <int> lcp;
int N;
string S;

void Init(string &st) {


S = st;
N = st.size();
sa.resize(N);
pos.resize(N);
lcp.resize(N);
for (int i = 0; i < (int)st.size(); i++) {
sa[i] = i;
pos[i] = st[i];
}
}

void buildSA() {
vector <int> tmp(N);
int gap;
auto cmp = [&](int i, int j) {
if (pos[i] != pos[j]) return pos[i] < pos[j];
i += gap;
j += gap;
if (i < N && j < N) return pos[i] < pos[j];
return i > j;
};
for (gap = 1; ; gap <<= 1) {
sort(all(sa), cmp);
for (int i = 0; i < N - 1; i++) tmp[i + 1] = tmp[i] +
cmp(sa[i], sa[i + 1]);
for (int i = 0; i < N; i++) pos[sa[i]] = tmp[i];
if (tmp[N - 1] == N - 1) break;
}
}

void buildLCP() {
for (int i = 0, k = 0; i < N; i++) {
if (pos[i] != N - 1) {
for (int j = sa[pos[i] + 1]; S[i + k] == S[j +
k]; ) ++k;
lcp[pos[i]] = k;
if (k) --k;
}
}
}
};

lineContainer

/**
* Author: Simon Lindholm
* Date: 2017-04-20
* License: CC0
* Source: own work
* Description: Container where you can add lines of the form kx+m, and query
maximum values at points x.
* Useful for dynamic programming (``convex hull trick'').
* Time: O(\log N)
* Status: stress-tested
*/
#pragma once

struct Line {
mutable ll k, m, p;
bool operator<(const Line& o) const { return k < o.k; }
bool operator<(ll x) const { return p < x; }
};

struct LineContainer : multiset<Line, less<>> {


// (for doubles, use inf = 1/.0, div(a,b) = a/b)
static const ll inf = LLONG_MAX;
ll div(ll a, ll b) { // floored division
return a / b - ((a ^ b) < 0 && a % b); }
bool isect(iterator x, iterator y) {
if (y == end()) return x->p = inf, 0;
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
else x->p = div(y->m - x->m, x->k - y->k);
return x->p >= y->p;
}
void add(ll k, ll m) {
auto z = insert({k, m, 0}), y = z++, x = y;
while (isect(y, z)) z = erase(z);
if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
while ((y = x) != begin() && (--x)->p >= y->p)
isect(x, erase(y));
}
ll query(ll x) {
assert(!empty());
auto l = *lower_bound(x);
return l.k * x + l.m;
}
};

Hungarian

namespace HungarianAlgo {
const int inf = 1e9;
const int MAXN = 201, MAXM = 201;

int c[MAXN][MAXM], fx[MAXN], fy[MAXM];


int matchX[MAXN], matchY[MAXM];
int trace[MAXM];
int d[MAXM], lnk[MAXM];
int startV, endV;
queue <int> q;
int N, M;

void init(int n, int m) {


memset(fx, -0x0f, sizeof fx);
N = n;
M = m;
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >>
c[i][j], c[i][j] = -c[i][j];
}

int getC(int x, int y) {


return c[x][y] - fx[x] - fy[y];
}

int findPath() {
while (q.size()) {
int u = q.front();
q.pop();
for (int v = 1; v <= M; v++) {
if (trace[v]) continue;
if (getC(u, v) == 0) {
trace[v] = u;
if (matchY[v] == 0) return v;
q.push(matchY[v]);
}
if (d[v] > getC(u, v)) {
d[v] = getC(u, v);
lnk[v] = u;
}
}
}
return 0;
}

void changeWeight() {
int delta = inf;
for (int i = 1; i <= M; i++) if (trace[i] == 0) delta = min(delta,
d[i]);
fx[startV] += delta;
for (int i = 1; i <= M; i++) {
if (trace[i]) {
fx[matchY[i]] += delta;
fy[i] -= delta;
} else {
d[i] -= delta;
if (d[i] == 0) {
trace[i] = lnk[i];
if (!matchY[i]) endV = i;
else q.push(matchY[i]);
}
}
}
}

void enLarge(int t) {
while (t) {
int s = trace[t];
int k = matchX[s];
matchX[s] = t;
matchY[t] = s;
t = k;
}
}

ll minimumMatching() {
for (startV = 1; startV <= N; startV++) {
while (q.size()) q.pop();
q.push(startV);
for (int i = 1; i <= M; i++) {
trace[i] = 0;
d[i] = getC(startV, i);
lnk[i] = startV;
}
endV = 0;
while (!endV) {
endV = findPath();
if (!endV) changeWeight();
}
enLarge(endV);
}

ll ans = 0;
for (int i = 1; i <= N; i++) {
ans += c[i][matchX[i]];
if (ans >= inf) return -1;
}
return ans;
}

void print() {
for (int i = 1; i <= N; i++) cout << -fx[i] << ' ';
cout << '\n';
for (int i = 1; i <= M; i++) cout << -fy[i] << ' ';
}
}

You might also like