zoukankan      html  css  js  c++  java
  • BZOJ4046 [Cerc2014] Pork barre

    我们把边按权值从大到小依次加入图中

    如果加到边权$V$,则当前的最小生成森林中边权$vin[V, V']$(其中$V'$是任意值)形成的森林的边权和就是对于询问$[V, V']$的答案

    由于点数不多,所以可以每次暴力$dfs$找环上最大边以及暴力删除。。。

    又由于是强制在线,于是用可持久化线段树维护不同权值的出现次数即可

      1 /**************************************************************
      2     Problem: 4046
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:8788 ms
      7     Memory:46132 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13  
     14 using namespace std;
     15 const int N = 1e3 + 5;
     16 const int M = 1e5 + 5;
     17 const int maxV = 1e6 + 5;
     18  
     19 int read();
     20  
     21 struct Edge {
     22     int x, y, v;
     23      
     24     inline bool operator < (const Edge &e) const {
     25         return v > e.v;
     26     }
     27      
     28     inline void get() {
     29         x = read(), y = read(), v = read();
     30     }
     31 } E[M];
     32  
     33 struct edge {
     34     int next, to, v;
     35     edge() {}
     36     edge(int _n, int _t, int _v) : next(_n), to(_t), v(_v) {}
     37 } e[M << 1];
     38  
     39 struct chair_tree {
     40     chair_tree *ls, *rs;
     41     int sum;
     42      
     43     #define Cnt 3500000
     44     inline void* operator new(size_t, chair_tree *_c = NULL, int f = 0) {
     45         static chair_tree mempool[Cnt], *c;
     46         if (f) c = mempool;
     47         if (_c == NULL)
     48             c -> ls = c -> rs = NULL, c -> sum = 0;
     49         else *c = *_c;
     50         return c++;
     51     }
     52     #undef Cnt
     53      
     54     #define mid (l + r >> 1)
     55     void modify(int l, int r, int pos, int d) {
     56         sum += d;
     57         if (l == r) return;
     58         if (pos <= mid) {
     59             ls = new(ls)chair_tree;
     60             ls -> modify(l, mid, pos, d);
     61         } else {
     62             rs = new(rs)chair_tree;
     63             rs -> modify(mid + 1, r, pos, d);
     64         }
     65     }
     66      
     67     int query(int l, int r, int L, int R) {
     68         if (L <= l && r <= R) return sum;
     69         int res = 0;
     70         if (ls && L <= mid) res += ls -> query(l, mid, L, R);
     71         if (rs && mid < R) res += rs -> query(mid + 1, r, L, R);
     72         return res;
     73     }
     74     #undef mid
     75 } *root[M];
     76  
     77 int n, m, ans;
     78 int first[N], tot;
     79 int fa[N];
     80 int tmp[M], len;
     81  
     82 inline void Add_Edges(int x, int y, int v) {
     83     e[++tot] = edge(first[x], y, v), first[x] = tot;
     84     e[++tot] = edge(first[y], x, v), first[y] = tot;
     85 }
     86  
     87 #define y e[x].to
     88 inline void Delete_Edge(int p, int q) {
     89     int x;
     90     if (e[first[p]].to == q) {
     91         first[p] = e[first[p]].next;
     92         return;
     93     }
     94     for (x = first[p]; x; x = e[x].next)
     95         if (e[e[x].next].to == q) {
     96             e[x].next = e[e[x].next].next;
     97             return;
     98         }
     99 }
    100  
    101 inline void Delete_Edges(int p, int q) {
    102     Delete_Edge(p, q);
    103     Delete_Edge(q, p);
    104 }
    105  
    106 int find_max(int p, int fa, int tar) {
    107     int x, tmp;
    108     for (x = first[p]; x; x = e[x].next)
    109         if (y != fa) {
    110             if (y == tar) return x;
    111             tmp = find_max(y, p, tar);
    112             if (tmp != -1) {
    113                 if (e[tmp].v > e[x].v) return tmp;
    114                 return x;
    115             }
    116         }
    117     return -1;
    118 }
    119 #undef y
    120  
    121 int find(int x) {
    122     return fa[x] == x ? x : fa[x] = find(fa[x]);
    123 }
    124  
    125 inline int get(int x) {
    126     return lower_bound(tmp + 1, tmp + len + 1, x) - tmp;
    127 }
    128  
    129 int main() {
    130     int T, now, i, x, y, Q;
    131     for (T = read(); T; --T) {
    132         n = read(), m = read(), ans = 0;
    133         for (i = 1; i <= n; ++i) fa[i] = i;
    134         for (i = 1; i <= m; ++i) {
    135             E[i].get();
    136             tmp[i] = E[i].v;
    137         }
    138         sort(E + 1, E + m + 1);
    139         sort(tmp + 1, tmp + m + 1), len = unique(tmp + 1, tmp + m + 1) - tmp - 1;
    140         memset(first, 0, sizeof(first)), tot = 1;
    141          
    142         root[len + 1] = new(NULL, 1)chair_tree;
    143         for (now = len, i = 1; now; --now) {
    144             root[now] = new(root[now + 1])chair_tree;
    145             for (; E[i].v == tmp[now] && i <= m; ++i) {
    146                 x = find(E[i].x), y = find(E[i].y);
    147                 if (x != y) fa[x] = y;
    148                 else {
    149                     x = find_max(E[i].x, 0, E[i].y);
    150                     Delete_Edges(e[x].to, e[x ^ 1].to);
    151                     root[now] -> modify(1, len, get(e[x].v), -e[x].v);
    152                 }
    153                 Add_Edges(E[i].x, E[i].y, E[i].v);
    154                 root[now] -> modify(1, len, get(E[i].v), E[i].v);
    155             }
    156         }
    157         for (Q = read(); Q; --Q) {
    158             x = read(), y = read();
    159             x = upper_bound(tmp + 1, tmp + len + 1, x - ans - 1) - tmp;
    160             y = upper_bound(tmp + 1, tmp + len + 1, y - ans) - tmp - 1;
    161             if (x > y) printf("%d
    ", ans = 0);
    162             else printf("%d
    ", ans = root[x] -> query(1, len, x, y));
    163         }
    164     }
    165     return 0;
    166 }
    167  
    168 inline int read() {
    169     static int x;
    170     static char ch;
    171     x = 0, ch = getchar();
    172     while (ch < '0' || '9' < ch)
    173         ch = getchar();
    174     while ('0' <= ch && ch <= '9') {
    175         x = x * 10 + ch - '0';
    176         ch = getchar();
    177     }
    178     return x;
    179 }
    View Code
  • 相关阅读:
    Valid Anagram
    数据结构与算法2016-06-02
    数据结构与算法2016-06-03
    Delete Node in a Linked List
    Move Zeroes
    Javascript 常用的工具函数,更新中...
    有用的Javascript,长期更新...
    sql基本语法
    Javascript 有用的奇淫技巧
    关于 Vue 的一些问题(面试中面试官想听到的答案)
  • 原文地址:https://www.cnblogs.com/rausen/p/4528842.html
Copyright © 2011-2022 走看看