板子2
字符串的最大最小表示法(周源)
最小
int MinRepresstation(char *s) {
int i = 0, j = 1, k;
int len = strlen(s);
for (int i = len; i < len * 2; i++) {
s[i] = s[i - len];
}
while (i < len && j < len) {
k = 0;
while (k < len && s[i+k] == s[j+k]) k++;
if (k == len) break;
if (s[i + k] > s[j + k])
i = max(i + k + 1, j + 1);
else
j = max(i + 1, j + k + 1);
}
return min(i, j);
/* 不加长写法 */
int i = 0, j = 1, k = 0;
while (i < len && j < len && k < len) {
int t = s[(i+k)%len] - s[(j+k)%len];
if (!t) k++;
else {
if (t > 0) i = i + k + 1;
else j = j + k + 1;
if (i == j) j++;
k = 0;
}
}
return min(i, j);
}
最大
int MaxRepresstation(char *s, int len) {
/* 实际已加长 len是原来的长度 */
int i = 0, j = 1, k;
while (i < len && j < len) {
k = 0;
while (k < len && s[i+k] == s[j+k]) k++;
if (k == len) break;
if (s[i + k] > s[j + k])
j = max(i + 1, j + k + 1);
else
i = max(i + k + 1, j + 1);
}
return min(i, j);
/* 不加长写法 */
int i = 0, j = 1, k = 0;
while (i < len && j < len && k < len) {
int t = s[(i+k)%len] - s[(j+k)%len];
if (!t) k++;
else {
if (t > 0) j = j + k + 1;
else i = i + k + 1;
if (i == j) j++;
k = 0;
}
}
return min(i, j);
}
浮点数比较大小
int sgn(db x) {
return x < -eps ? -1 : x < eps ? 0 : 1;
}
sgn(a - b) > 0
sgn(a - b) < 0
sgn(a - b) == 0
sgn(a - b) >= 0
sgn(a - b) <= 0
莫队算法(BZOJ 2038)
struct Query {
ll l, r, id;
ll q, p;
void get() { //最简分数
ll gd = __gcd(q, p);
p /= gd, q /= gd;
}
} q[maxn];
int a[maxn], f[maxn], pos[maxn];
bool cmp1(const Query &a, const Query &b) {
if (pos[a.l] == pos[b.l])
return a.r < b.r;
return pos[a.l] < pos[b.l]; //以分块为第一关键字
}
bool cmp2(const Query &a, const Query &b) {
return a.id < b.id; //按顺序输出
}
void solve() {
int n, m;
while (cin >> n >> m) {
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; i++)
scanf("%d", a + i);
int limit = sqrt((db)n + 0.5); //每一块的大小
for (int i = 1; i <= n; i++)
pos[i] = (i-1) / limit + 1; //分块,我也不知道为啥要(i-1) / limit + 1,我觉得直接 i / limit就可以了呀
for (int i = 1; i <= m; i++) {
scanf("%lld%lld", &q[i].l, &q[i].r);
q[i].id = i;
}
sort(q+1, q+1+m, cmp1);
ll sum = 0;
a[0] = 0;
int l = 1, r = 0;
for (int i = 1; i <= m; i++) { //移动这里比较烦 这题的我l表示的其实是l-1,r就是r
while (l < q[i].l) {
sum -= (f[a[l]] << 1) - 1;
f[a[l]]--;
l++;
}
while (l > q[i].l) {
l--;
sum += (f[a[l]] << 1) + 1;
f[a[l]]++;
}
while (r < q[i].r) {
r++;
sum += (f[a[r]] << 1) + 1;
f[a[r]]++;
}
while (r > q[i].r) {
sum -= (f[a[r]] << 1) - 1;
f[a[r]]--;
r--;
}
q[i].q = sum - (q[i].r - q[i].l + 1);
q[i].p = (q[i].r - q[i].l + 1) * (q[i].r - q[i].l);
q[i].get();
}
sort(q+1, q+1+m, cmp2);
for (int i = 1; i <= m; i++)
printf("%lld/%lld\n", q[i].q, q[i].p);
}
}
2-SAT(hdu1814, O(nm))
int head[maxn];
struct Edge {
int v, next;
} e[maxn<<1];
int cnt, pri[maxn], col[maxn], top;
void init() {
memset(head, -1, sizeof(head));
cnt = 0;
}
void add(int u, int v) {
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
bool dfs(int u) {
if (col[u^1]) return false; //同组的已经被标记了,那么当前这种就不行
if (col[u]) return true;
col[u] = true;
pri[++top] = u;
for (int i = head[u]; ~i; i = e[i].next)
if (!dfs(e[i].v)) return false;
return true;
}
bool solve(int n) {
memset(col, 0, sizeof(col));
for (int i = 0; i < 2*n; i += 2) {
if (col[i] || col[i^1]) continue;
top = 0;
if (!dfs(i)) {
for (int j = 1; j <= top; j++)
col[pri[j]] = false;
if (!dfs(i^1))
return false;
}
}
return true;
}
void solve() {
int n, m;
while (cin >> n >> m) {
init();
for (int i = 1; i <= m; i++) {
int u, v; scanf("%d%d", &u, &v);
u--, v--;
add(u, v^1); add(v, u^1); //1 和 2属于一组, 用 0 和 1来表示直接用^就可以相互转换了
}
if (solve(n)) {
for (int i = 0; i < 2*n ; i += 2)
if (col[i]) cout << i+1 << endl;
else cout << i+2 << endl;
}
else cout << "NIE\n";
}
}
网络流dinic(HDU4309,状态压缩+网络流,刘汝佳的板子太坑。。 只能换个板子。。
int head[maxn], cnt;
int n, m, s, t;
int d[maxn], cur[maxn], x[maxn];
bool vis[maxn];
struct Edge {
int v, f, next;
} e[maxn];
void init() {
memset(head, -1, sizeof(head));
cnt = 0;
}
void add(int u, int v, int cap) {
e[cnt].f = cap;
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
void AddEdge(int u, int v, int cap) {
add(u, v, cap);
add(v, u, 0);
}
bool BFS() {
memset(vis, 0, sizeof(vis));
queue<int> q;
q.push(s);
vis[s] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = head[u]; ~i; i = e[i].next) {
if (!vis[e[i].v] && e[i].f) { //只考虑残量网络的弧
vis[e[i].v] = 1;
d[e[i].v] = d[u] + 1;
q.push(e[i].v);
}
}
}
return vis[t];
}
int dfs(int u, int a) {
if (u == t) return a;
int flow = 0;
for (int i = head[u]; a && ~i; i = e[i].next) {
if (e[i].f && d[u] + 1 == d[e[i].v]) {
int dd = dfs(e[i].v, min(e[i].f, a));
e[i].f -= dd;
e[i^1].f += dd;
flow += dd;
a -= dd;
}
}
return flow;
}
int Dinic() {
int flow = 0;
while (BFS()) {
flow += dfs(s, INF);
}
return flow;
}
void solve() {
while (cin >> n >> m) {
s = 0, t = n+1;
for (int i = 1; i <= n; i++) {
scanf("%d", &x[i]);
}
int num = 0;
int ub[20], vb[20], c[20];
int u[maxn], v[maxn], w[maxn], p[maxn];
int nu = 0, flag = 0;
for (int i = 1; i <= m; i++) {
int tu, tv, tw, tp;
scanf("%d%d%d%d", &tu, &tv, &tw, &tp);
if (tp < 0) flag = 1;
if (tp > 0) {
ub[num] = tu, vb[num] = tv;
c[num++] = tw;
}
else {
u[nu] = tu, v[nu] = tv, w[nu] = tw;
p[nu++] = tp;
}
}
if(!flag){
printf("Poor Heaven Empire\n");
continue;
}
int ans = 0, cos;
for (int i = 0; i < (1<<num); i++) {
int co = 0;
init();
for (int j = 1; j <= n; j++)
AddEdge(s, j, x[j]);
for (int j = 0; j < num; j++) {
if (i & (1<<j)) {
co += c[j];
AddEdge(ub[j], vb[j], INF);
}
else AddEdge(ub[j], vb[j], 1);
}
for (int j = 0; j < nu; j++) {
if (p[j] == 0) {
AddEdge(u[j], v[j], INF);
}
else {
AddEdge(u[j], v[j], INF);
AddEdge(u[j], t, w[j]);
}
}
int tmp = Dinic();
if (tmp > ans) {
ans = tmp;
cos = co;
}
}
cout << ans << ' ' << cos << endl;
}
}
)

浙公网安备 33010602011771号