• 【 bzoj4537】HNOI2016 最小公倍数


      首先将边按a的值分组,每$sqrt{m}$一组。

      对于每一组,将符合一组a的询问选出来,将这些询问和这一块之前的边(a一定小于这些询问)按b排序,然后交替插入,询问,对于一个询问,在当前块也有可能有满足的边,我们将其加入,考虑后并撤销,由于块大小是$sqrt{m}$所以复杂度正确。

      注意 : 1.并查集不能路径压缩,否则无法撤销;

                  2.在筛选一组的询问时,不要让一个询问被考虑多次,也就是说用询问的a小于终点后的那条边的a作为筛选条件,否则假如所有的a一样,那么每个询问每次都会被考虑一遍。

      复杂度为$sqrt{m}mlog(m) + Q sqrt{m}$

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define drep(i, a, b) for (int i = a; i >= b; i--)
     4 #define REP(i, a, b) for (int i = a; i < b; i++)
     5 #define pb push_back
     6 #define mp make_pair
     7 #define xx first
     8 #define yy second
     9 using namespace std;
    10 typedef long long ll;
    11 typedef pair<int, int> pii;
    12 const int inf = 0x3f3f3f3f;
    13 const ll INF = 0x3f3f3f3f3f3f3f3fll;
    14 template <typename T> void Max(T& a, T b) { if (b > a) a = b; }
    15 //*********************************
    16 
    17 const int maxn = 50005, maxm = 100005;
    18 struct DATA {
    19     int u, v, a, b, id;
    20 } e[maxm], q[maxn], tmp[maxn];
    21 bool cmpa(DATA a, DATA b) { return a.a < b.a; }
    22 bool cmpb(DATA a, DATA b) { return a.b < b.b; }
    23 
    24 struct Option {
    25     int x, y, xmaxa, xmaxb, sz, ymaxa, ymaxb, f; Option() {}
    26     Option(int _x, int _y, int _xmaxa, int _xmaxb, int _sz, int _ymaxa, int _ymaxb, int _f) :
    27         x(_x), y(_y), xmaxa(_xmaxa), xmaxb(_xmaxb), sz(_sz), ymaxa(_ymaxa), ymaxb(_ymaxb), f(_f) {}
    28 } op[maxn];
    29 
    30 int top;
    31 int fa[maxn], sz[maxn], maxa[maxn], maxb[maxn];
    32 int ans[maxn];
    33 int getfather(int x) { return fa[x] == x ? x : getfather(fa[x]); }
    34 void merge(int x, int y, int a, int b) {
    35     int fx = getfather(x), fy = getfather(y);
    36     if (sz[fx] < sz[fy]) swap(fx, fy);
    37     op[++top] = (Option){fx, fy, maxa[fx], maxb[fx], sz[fx], maxa[fy], maxb[fy], fa[fy]};
    38     if (fx == fy) {
    39         maxa[fx] = max(maxa[fx], a);
    40         maxb[fx] = max(maxb[fx], b);
    41         return;
    42     }
    43     sz[fx] += sz[fy];
    44     maxa[fx] = max(maxa[fx], max(maxa[fy], a));
    45     maxb[fx] = max(maxb[fx], max(maxb[fy], b));
    46     fa[fy] = fx;
    47 }
    48 
    49 void retrace() {
    50     drep(i, top, 1) {
    51         maxa[op[i].x] = op[i].xmaxa;
    52         maxb[op[i].x] = op[i].xmaxb;
    53         maxa[op[i].y] = op[i].ymaxa;
    54         maxb[op[i].y] = op[i].ymaxb;
    55         fa[op[i].y] = op[i].f;
    56         sz[op[i].x] = op[i].sz;
    57     }
    58 }
    59 
    60 int main() {
    61     /*
    62     freopen("multiple.in", "r", stdin);
    63     freopen("multiple.out", "w", stdout);
    64     */
    65     int n, m; scanf("%d%d", &n, &m);
    66     rep(i, 1, m) scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].a, &e[i].b);
    67     int Q; scanf("%d", &Q);
    68     rep(i, 1, Q) scanf("%d%d%d%d", &q[i].u, &q[i].v, &q[i].a, &q[i].b), q[i].id = i;
    69     int Sz = sqrt(m);
    70 
    71     sort(e + 1, e + 1 + m, cmpa);
    72     sort(q + 1, q + 1 + Q, cmpb);
    73 
    74     for (int st = 1; st <= m; st += Sz) {
    75         int end = min(st + Sz - 1, m);
    76 
    77         int cnt(0);
    78         for (int i = 1; i <= Q; i++) if (q[i].a >= e[st].a && (st + Sz > m || q[i].a < e[end + 1].a)) tmp[++cnt] = q[i];
    79         if (!cnt) continue;
    80 
    81         sort(e + 1, e + st, cmpb);
    82 
    83         rep(i, 1, n) fa[i] = i, sz[i] = 1, maxa[i] = maxb[i] = -1;
    84         for (int k = 1, j = 1; k <= cnt; k++) {
    85             while (e[j].b <= tmp[k].b && j < st) merge(e[j].u, e[j].v, e[j].a, e[j].b), j++;
    86 
    87             top = 0;
    88             rep(i, st, end) if (e[i].a <= tmp[k].a && e[i].b <= tmp[k].b) merge(e[i].u, e[i].v, e[i].a, e[i].b);
    89             int fx = getfather(tmp[k].u), fy = getfather(tmp[k].v);
    90             if (fa[fx] == fa[fy] && maxa[fx] == tmp[k].a && maxb[fx] == tmp[k].b) ans[tmp[k].id] = 1;
    91             retrace();
    92         }
    93 
    94     }
    95     rep(i, 1, Q) if (ans[i]) puts("Yes"); else puts("No");
    96 
    97     return 0;
    98 }
    multiple
  • 相关阅读:
    offsetwidth/clientwidth的区别
    React-redux-webpack项目总结之用到的Es6基本语法
    【转载】WebService到底是什么?
    W3School WebService教程
    【转载】C++之继承与多态
    抽象类指针
    const函数
    指针和const限定符
    void与void *
    构造函数初始化
  • 原文地址:https://www.cnblogs.com/y7070/p/5412793.html
Copyright © 2020-2023  润新知