zoukankan      html  css  js  c++  java
  • 【 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
  • 相关阅读:
    AS将一个项目导入到另一个项目中
    Android Studio出现:Cause: unable to find valid certification path to requested target
    小米手机Toast带app名称
    PopupWindow 点击外部区域无法关闭的问题
    EditText inputType类型整理
    Fragment通过接口回调向父Activity传值
    Android selector一些坑
    Installation failed with message Failed to commit install session 634765663 with command cmd package
    旷视上海研究院机器人方向招聘
    语义SLAM的数据关联和语义定位(四)多目标测量概率模型
  • 原文地址:https://www.cnblogs.com/y7070/p/5412793.html
Copyright © 2011-2022 走看看