板子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;
    }
}

  

posted @ 2017-03-01 21:07  ost_xg  阅读(201)  评论(0)    收藏  举报