首页 > 其他 > 详细

Codeforces Round #265 (Div. 1) E. The Classic Problem

时间:2020-02-01 17:58:55      阅读:58      评论:0      收藏:0      [点我收藏+]

 

主席树实现二进制高精度。

技术分享图片
#include <bits/stdc++.h>
using namespace std;

template<typename T>
inline void read(T &x) {
    x = 0; T f = 1; char ch = getchar();
    while (ch < 0 || ch > 9) { if (ch == -) f = -1; ch = getchar(); }
    while (ch >= 0 && ch <= 9) { x = x * 10 + ch - 48; ch = getchar(); }
    x *= f;    
}

const int N = 1e5 + 7;
const int MOD = 1e9 + 7;
int bin[N << 1], n, m, ALL, root[N];

struct E {
    int v, ne, dis;
} e[N << 2];
int head[N], cnt, pre[N];

inline void add(int u, int v, int d) {
    e[++cnt].v = v; e[cnt].ne = head[u]; e[cnt].dis = d; head[u] = cnt;
}

struct Seg {
    struct Tree {
        int lp, rp, sum;
    } tree[N * 40];
    int tol;
    bool cmp(int p, int q, int l, int r) {
        if (l == r) return tree[p].sum > tree[q].sum;
        int mid = l + r >> 1;
        if (tree[tree[p].rp].sum == tree[tree[q].rp].sum) 
            return cmp(tree[p].lp, tree[q].lp, l, mid);
        return cmp(tree[p].rp, tree[q].rp, mid + 1, r);
    }
    int update(int &p, int q, int l, int r, int pos) {
        tree[p = ++tol] = tree[q];
        if (l == r) {
            tree[p].sum = tree[q].sum ^ 1;
            return tree[q].sum;
        }
        int res;
        int mid = l + r >> 1;
        if (pos > mid) res = update(tree[p].rp, tree[q].rp, mid + 1, r, pos);
        else {
            res = update(tree[p].lp, tree[q].lp, l, mid, pos);
            if (res)
                res = update(tree[p].rp, tree[q].rp, mid + 1, r, mid + 1);
        }
        tree[p].sum = (1LL * tree[tree[p].rp].sum * bin[mid - l + 1] % MOD + 1LL * tree[tree[p].lp].sum) % MOD;
        return res;
    }
} seg;

struct Node {
    int u, rt;
    bool operator < (const Node &rhs) const {
        return seg.cmp(rt, rhs.rt, 0, ALL);
    }
};

priority_queue<Node> que;

void print(int s, int now, int dep) {
    if (now == s) {
        printf("%d\n%d ", dep, now);
        return;
    }
    print(s, pre[now], dep + 1);
    printf("%d ", now);
}

void out(int s, int t) {
    printf("%d\n", seg.tree[root[t]].sum);
    print(s, t, 1);
    puts("");
}

void dijkstra(int s, int t) {
    que.push((Node){s, root[s]});
    while (!que.empty()) {
        Node p = que.top(); que.pop();
        int u = p.u;
        if (p.rt != root[u]) continue;
        if (u == t) {
            out(s, t);
            return;
        }
        for (int i = head[u]; i; i = e[i].ne) {
            int v = e[i].v, rt;
            seg.update(rt, root[u], 0, ALL, e[i].dis);
            if (!root[v] || seg.cmp(root[v], rt, 0, ALL)) {
                root[v] = rt;
                que.push((Node){v, root[v]});
                pre[v] = u;
            }
        }
    }
    puts("-1");
}

int main() {
    read(n), read(m);
    for (int i = bin[0] = 1; i < N * 2; i++)
        bin[i] = 2LL * bin[i - 1] % MOD;
    while (m--) {
        int u, v, k;
        read(u), read(v), read(k);
        add(u, v, k);
        add(v, u, k);
        ALL = max(ALL, k);
    }
    ALL += 100;
    int s, t;
    read(s), read(t);
    dijkstra(s, t);
    return 0;
}
View Code

 

Codeforces Round #265 (Div. 1) E. The Classic Problem

原文:https://www.cnblogs.com/Mrzdtz220/p/12249066.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!