/ @@18khV /

记录详情

Accepted

foo.cc: In function 'int NG::iseg_node(int, int)':
foo.cc:59:29: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
         int mid = info[o].l + info[o].r >> 1;
                   ~~~~~~~~~~^~~~~~~~~~~
foo.cc: In function 'int NG::oseg_node(int, int)':
foo.cc:77:29: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
         int mid = info[o].l + info[o].r >> 1;
                   ~~~~~~~~~~^~~~~~~~~~~
foo.cc: In function 'void NG::getintv(int, int, int)':
foo.cc:99:33: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
             int mid = info[o].l + info[o].r >> 1;
                       ~~~~~~~~~~^~~~~~~~~~~
foo.cc: In member function 'void Tree::rmq_init()':
foo.cc:182:58: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
                 int a = mnp[j-1][i], b = mnp[j-1][i+(1<<j-1)];
                                                         ~^~

自豪的采用 HydroJudge 进行评测(github.com/hydro-dev/HydroJudge)
正在同步测试数据,请稍后
{"receive":"2020-07-23T09:18:12.201Z","handle":"2020-07-23T09:18:12.201Z","cache_start":"2020-07-23T09:18:12.207Z","read_cases":"2020-07-23T09:18:26.804Z","judge":"2020-07-23T09:18:26.805Z","done":"2020-07-23T09:18:43.775Z"}
# 状态 耗时 内存占用
#1 Accepted 249ms 26.953 MiB
#2 Accepted 247ms 35.34 MiB
#3 Accepted 260ms 35.387 MiB
#4 Accepted 256ms 27.211 MiB
#5 Accepted 277ms 30.617 MiB
#6 Accepted 479ms 46.035 MiB
#7 Accepted 543ms 42.016 MiB
#8 Accepted 610ms 47.168 MiB
#9 Accepted 668ms 39.832 MiB
#10 Accepted 745ms 47.895 MiB
#11 Accepted 817ms 39.387 MiB
#12 Accepted 883ms 46.785 MiB
#13 Accepted 963ms 38.996 MiB
#14 Accepted 1045ms 47.066 MiB
#15 Accepted 1060ms 42.133 MiB
#16 Accepted 1128ms 47.367 MiB
#17 Accepted 1198ms 41.949 MiB
#18 Accepted 1258ms 46.773 MiB
#19 Accepted 1312ms 39.113 MiB
#20 Accepted 1377ms 49.59 MiB

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <queue>
using namespace std;
 
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
    if(Head == Tail) {
        int l = fread(buffer, 1, BufferSize, stdin);
        Tail = (Head = buffer) + l;
    }
    return *Head++;
}
int read() {
    int x = 0, f = 1; char c = Getchar();
    while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    return x * f;
}
 
#define maxn 100010
#define maxnode 1000010
#define maxm 6000380
#define maxlog 17
#define ool (1ll << 60)
#define LL long long
 
namespace NG {
    int ToT, val[maxnode];
     
    int iRt[maxn], oRt[maxn];
    struct Seg_info {
        int l, r, lc, rc;
        Seg_info() {}
        Seg_info(int _1, int _2, int _3, int _4): l(_1), r(_2), lc(_3), rc(_4) {}
    } info[maxnode];
     
    int m, head[maxnode], nxt[maxm], to[maxm], dist[maxm];
    void init() {
        ToT = 0;
        memset(val, 0, sizeof(val));
        m = 0; memset(head, 0, sizeof(head));
        return ;
    }
     
    void AddEdge(int a, int b, int c) {
//      printf("NG::AddEdge(%d -> %d : %d)\n", a, b, c);
        to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
        return ;
    }
     
    int iseg_node(int o, int pos) {
        if(info[o].l == info[o].r) return o;
        int mid = info[o].l + info[o].r >> 1;
        if(pos <= mid) {
            if(!info[o].lc) {
                info[o].lc = ++ToT;
                info[info[o].lc] = Seg_info(info[o].l, mid, 0, 0);
                AddEdge(info[o].lc, o, 0);
            }
            return iseg_node(info[o].lc, pos);
        }
        if(!info[o].rc) {
            info[o].rc = ++ToT;
            info[info[o].rc] = Seg_info(mid + 1, info[o].r, 0, 0);
            AddEdge(info[o].rc, o, 0);
        }
        return iseg_node(info[o].rc, pos);
    }
    int oseg_node(int o, int pos) {
        if(info[o].l == info[o].r) return o;
        int mid = info[o].l + info[o].r >> 1;
        if(pos <= mid) {
            if(!info[o].lc) {
                info[o].lc = ++ToT;
                info[info[o].lc] = Seg_info(info[o].l, mid, 0, 0);
                AddEdge(o, info[o].lc, 0);
            }
            return oseg_node(info[o].lc, pos);
        }
        if(!info[o].rc) {
            info[o].rc = ++ToT;
            info[info[o].rc] = Seg_info(mid + 1, info[o].r, 0, 0);
            AddEdge(o, info[o].rc, 0);
        }
        return oseg_node(info[o].rc, pos);
    }
     
    int cIntv, Intv[maxn];
    void getintv(int o, int ql, int qr) {
        if(!o) return ;
        if(ql <= info[o].l && info[o].r <= qr) Intv[++cIntv] = o;
        else {
            int mid = info[o].l + info[o].r >> 1;
            if(ql <= mid) getintv(info[o].lc, ql, qr);
            if(qr > mid) getintv(info[o].rc, ql, qr);
        }
        return ;
    }
    void GetIntv(int o, int ql, int qr) {
        cIntv = 0;
        if(ql > qr) return ;
        getintv(o, ql, qr);
        return ;
    }
     
    struct Node {
        int u; LL d;
        Node() {}
        Node(int _, LL __): u(_), d(__) {}
        bool operator < (const Node& t) const { return d > t.d; }
    };
    priority_queue <Node> Q;
    bool vis[maxnode];
    LL d[maxnode];
    void ShortPath(int s) {
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= ToT; i++) d[i] = ool;
        d[s] = 0; Q.push(Node(s, 0));
        while(!Q.empty()) {
            int u = Q.top().u; Q.pop();
//          printf("(u)%d ", u);
            if(vis[u]) continue;
            vis[u] = 1;
            for(int e = head[u]; e; e = nxt[e]) if(d[to[e]] > d[u] + dist[e] + val[to[e]]) {
                d[to[e]] = d[u] + dist[e] + val[to[e]];
                if(!vis[to[e]]) Q.push(Node(to[e], d[to[e]]));
            }
        }
        return ;
    }
}
 
struct Edge {
    int from, to, dist, tnode;
    Edge() {}
    Edge(int _1, int _2, int _3, int _4): from(_1), to(_2), dist(_3), tnode(_4) {}
} es[maxn];
struct Graph {
    int m, hto[maxn], nto[maxn], hfr[maxn], nfr[maxn];
     
    void init() { m = 0; memset(hto, 0, sizeof(hto)); memset(hfr, 0, sizeof(hfr)); return ; }
     
    void AddEdge(int a, int b, int c, int d) {
        es[++m] = Edge(a, b, c, d);
        nto[m] = hto[a]; hto[a] = m;
        nfr[m] = hfr[b]; hfr[b] = m;
        return ;
    }
} G;
 
struct Tree {
    int n, m, head[maxn], nxt[maxn], to[maxn];
    int dep[maxn], Log[maxn<<1], mnp[maxlog][maxn<<1], pos[maxn], clo;
     
    void init() { m = 0; memset(head, 0, sizeof(head)); clo = 0; return ; }
     
    void AddEdge(int a, int b) {
        to[++m] = b; nxt[m] = head[a]; head[a] = m;
        return ;
    }
     
    void build(int u) {
        mnp[0][++clo] = u; pos[u] = clo;
        for(int e = head[u]; e; e = nxt[e]) {
            dep[to[e]] = dep[u] + 1;
            build(to[e]);
            mnp[0][++clo] = u;
        }
        return ;
    }
    void rmq_init() {
        Log[1] = 0;
        for(int i = 2; i <= clo; i++) Log[i] = Log[i>>1] + 1;
        for(int j = 1; (1 << j) <= clo; j++)
            for(int i = 1; i + (1 << j) - 1 <= clo; i++) {
                int a = mnp[j-1][i], b = mnp[j-1][i+(1<<j-1)];
                mnp[j][i] = dep[a] < dep[b] ? a : b;
            }
        return ;
    }
    int lca(int a, int b) {
        int l = pos[a], r = pos[b];
        if(l > r) swap(l, r);
        int t = Log[r-l+1];
        a = mnp[t][l]; b = mnp[t][r-(1<<t)+1];
        return dep[a] < dep[b] ? a : b;
    }
    int cdist(int a, int b) {
        return dep[a] + dep[b] - (dep[lca(a,b)] << 1);
    }
} tree;
 
bool cmp(int a, int b) { return tree.pos[a] < tree.pos[b]; }
struct VTree {
    int n, m, head[maxn], nxt[maxn], to[maxn], dist[maxn];
    int nodes[maxn], iN[maxn], ci, oN[maxn], co;
    int dl[maxn], dr[maxn], clo;
    int iRt, oRt, buff[maxn], cbuff;
     
    void init() {
        m = 0; memset(head, 0, sizeof(head));
        return ;
    }
     
    void AddEdge(int a, int b, int c) {
        to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
        return ;
    }
     
    void build(int u) {
        dl[u] = ++clo;
        for(int e = head[u]; e; e = nxt[e]) build(to[e]);
        dr[u] = clo;
        return ;
    }
     
    void AddEdges(int u) {
//      printf("AddEdgessssssssss(%d) [%d, %d] %d\n", u, dl[u], dr[u], NG::m);
        NG::GetIntv(iRt, dl[u], dl[u]);
        if(NG::cIntv) {
            int x = NG::Intv[1];
            NG::GetIntv(oRt, dl[u], dr[u]);
//          printf("[%d, %d]: %d\n", dl[u], dr[u], NG::cIntv);
            if(NG::cIntv) {
                for(int i = 1; i <= NG::cIntv; i++) {
                    NG::AddEdge(x, NG::Intv[i], tree.dep[u]);
//                  printf("HERE@@@@@@@ %d -> %d : %d\n", x, NG::Intv[i], tree.dep[u]);
                }
            }
        }
        NG::GetIntv(oRt, dl[u], dl[u]);
        if(NG::cIntv) {
            int x = NG::Intv[1];
            NG::GetIntv(iRt, dl[u] + 1, dr[u]);
            if(NG::cIntv) {
                for(int i = 1; i <= NG::cIntv; i++) {
                    NG::AddEdge(NG::Intv[i], x, tree.dep[u]);
//                  printf("HERE@@@@@@@ %d -> %d : %d | we are here %d\n", NG::Intv[i], x, tree.dep[u], u);
                }
            }
        }
        for(int e = head[u]; e; e = nxt[e]) {
            NG::GetIntv(iRt, dl[to[e]], dr[to[e]]);
            if(NG::cIntv) {
                cbuff = NG::cIntv;
                for(int i = 1; i <= cbuff; i++) buff[i] = NG::Intv[i];
            }
            else continue;
            int newnode = 0;
            NG::GetIntv(oRt, dl[u] + 1, dl[to[e]] - 1);
            if(NG::cIntv) {
                newnode = ++NG::ToT;
                for(int i = 1; i <= cbuff; i++) NG::AddEdge(buff[i], newnode, tree.dep[u]);
                for(int i = 1; i <= NG::cIntv; i++) NG::AddEdge(newnode, NG::Intv[i], 0);
            }
            NG::GetIntv(oRt, dr[to[e]] + 1, dr[u]);
            if(NG::cIntv) {
                if(newnode) for(int i = 1; i <= NG::cIntv; i++) NG::AddEdge(newnode, NG::Intv[i], 0);
                else {
                    newnode = ++NG::ToT;
                    for(int i = 1; i <= cbuff; i++) NG::AddEdge(buff[i], newnode, tree.dep[u]);
                    for(int i = 1; i <= NG::cIntv; i++) NG::AddEdge(newnode, NG::Intv[i], 0);
                }
            }
        }
        /*printf("(u)%d: ", u);
        for(int e = head[u]; e; e = nxt[e]) printf("%d ", to[e]);
        printf("to[e] ends\n");*/
        for(int e = head[u]; e; e = nxt[e]) AddEdges(to[e]);
//      printf("return to %d [%d, %d]\n", u, dl[u], dr[u]);
        return ;
    }
     
    void G_build(int u) {
        init();
        n = ci = co = 0;
        for(int e = G.hfr[u]; e; e = G.nfr[e]) iN[++ci] = e, nodes[++n] = es[e].tnode;
        for(int e = G.hto[u]; e; e = G.nto[e]) oN[++co] = e, nodes[++n] = es[e].tnode;
        if(!ci || !co) return ;
        sort(nodes + 1, nodes + n + 1, cmp);
        int t = n;
        for(int i = 1; i < t; i++) nodes[++n] = tree.lca(nodes[i], nodes[i+1]);
        sort(nodes + 1, nodes + n + 1, cmp);
        n = unique(nodes + 1, nodes + n + 1) - nodes - 1;
        for(int i = 1; i < n; i++) {
            int a = nodes[i], b = nodes[i+1], c = tree.lca(a, b);
            AddEdge(c, b, tree.cdist(c, b));
        }
        clo = 0;
        build(nodes[1]);
        NG::info[iRt = NG::iRt[u] = ++NG::ToT] = NG::Seg_info(1, clo, 0, 0);
        NG::info[oRt = NG::oRt[u] = ++NG::ToT] = NG::Seg_info(1, clo, 0, 0);
//      printf("G_build(%d) %d %d %d\n", u, n, clo, nodes[1]);
        for(int i = 1; i <= ci; i++) {
            int u = NG::iseg_node(iRt, dl[es[iN[i]].tnode]);
            NG::AddEdge(iN[i], u, 0);
        }
        for(int i = 1; i <= co; i++) {
            int u = NG::oseg_node(oRt, dl[es[oN[i]].tnode]);
            NG::AddEdge(u, oN[i], 0);
        }
        AddEdges(nodes[1]);
        return ;
    }
} vtree;
 
LL Ans[maxn];
 
void work() {
    G.init(); tree.init();
     
    int n = read(), m = read(), k = read();
//  printf("%d %d %d\n", n, m, k);
    for(int i = 1; i <= m; i++) {
        int a = read(), b = read(), c = read(), d = read();
        G.AddEdge(a, b, c, d);
    }
     
    NG::init();
    NG::ToT = m;
    for(int i = 1; i <= G.m; i++) NG::val[i] = es[i].dist;
    int Start = ++NG::ToT;
    for(int e = G.hto[1]; e; e = G.nto[e]) NG::AddEdge(Start, e, 0);
     
    for(int i = 1; i < k; i++) {
        int a = read(), b = read(); read();
        tree.AddEdge(a, b);
    }
    tree.build(1); tree.rmq_init();
     
    for(int i = 1; i <= n; i++) vtree.G_build(i);
     
//  printf("ToT: %d %d\n", NG::ToT, NG::m);
    NG::ShortPath(Start);
    for(int i = 1; i <= n; i++) Ans[i] = ool;
    for(int i = 1; i <= G.m; i++) Ans[es[i].to] = min(Ans[es[i].to], NG::d[i]);
     
    for(int i = 2; i <= n; i++) printf("%lld\n", Ans[i]);
     
    return ;
}
 
int main() {
    int T = read();
    while(T--) work();
     
    return 0;
}

信息

递交者
类型
递交
题目
P1017 天才黑客
题目数据
下载
语言
C++
递交时间
2020-07-23 17:18:12
评测时间
2020-07-23 17:18:12
评测机
分数
100
总耗时
15386ms
峰值内存
49.59 MiB