• bzoj3551 Peaks加强版


    强制在线。

    在kruskal重构树上线段树合并即可。

    题意有毒,ans = -1的时候下一次不异或。

      1 /**************************************************************
      2     Problem: 3551
      3     Language: C++
      4     Result: Accepted
      5     Time:19204 ms
      6     Memory:126608 kb
      7 ****************************************************************/
      8  
      9 #include <cstdio>
     10 #include <algorithm>
     11 #include <cstring>
     12  
     13 const int N = 100010, M = 500010, V = 8500010;
     14  
     15 struct Edge {
     16     int x, y, h;
     17     inline bool operator <(const Edge &w) const {
     18         return h < w.h;
     19     }
     20 }edge[M];
     21  
     22 int val[N], X[N];
     23 int ls[V], rs[V], sum[V], tot;
     24 int num, fa[N * 2][20], h[N * 2], rt[N * 2], siz[N * 2], pw[N * 2];
     25  
     26 namespace ufs {
     27     int fa[N * 2];
     28     inline void init(int n) {
     29         for(int i = 1; i <= n; i++) {
     30             fa[i] = i;
     31         }
     32         return;
     33     }
     34     int find(int x) {
     35         if(x == fa[x]) return x;
     36         return fa[x] = find(fa[x]);
     37     }
     38     inline void merge(int x, int y) {
     39         fa[find(y)] = find(x);
     40         return;
     41     }
     42     inline bool check(int x, int y) {
     43         return find(x) == find(y);
     44     }
     45 }
     46  
     47 int merge(int x, int y) {
     48     if(!x || !y) return x | y;
     49     int o = ++tot;
     50     sum[o] = sum[x] + sum[y];
     51     ls[o] = merge(ls[x], ls[y]);
     52     rs[o] = merge(rs[x], rs[y]);
     53     return o;
     54 }
     55  
     56 void add(int p, int l, int r, int &o) {
     57     if(!o) o = ++tot;
     58     sum[o] = 1;
     59     if(l == r) return;
     60     int mid = (l + r) >> 1;
     61     if(p <= mid) add(p, l, mid, ls[o]);
     62     else add(p, mid + 1, r, rs[o]);
     63     return;
     64 }
     65  
     66 int ask(int k, int l, int r, int o) {
     67     //printf("%d %d %d %d 
    ", k, l, r, o);
     68     if(l == r) return r;
     69     int mid = (l + r) >> 1;
     70     if(k <= sum[rs[o]]) return ask(k, mid + 1, r, rs[o]);
     71     else return ask(k - sum[rs[o]], l, mid, ls[o]);
     72 }
     73  
     74 inline int getPos(int x, int H) {
     75     int t = pw[num];
     76     while(t >= 0 && fa[x][0] && h[fa[x][0]] <= H) {
     77         if(fa[x][t] && h[fa[x][t]] <= H) {
     78             x = fa[x][t];
     79         }
     80         t--;
     81     }
     82     return x;
     83 }
     84  
     85 int main() {
     86  
     87     //freopen("in.in", "r", stdin);
     88     //freopen("my.out", "w", stdout);
     89  
     90     int n, m, q;
     91     scanf("%d%d%d", &n, &m, &q);
     92     num = n;
     93     ufs::init(n + n);
     94     for(int i = 1; i <= n; i++) {
     95         scanf("%d", &val[i]);
     96         X[i] = val[i];
     97     }
     98     std::sort(X + 1, X + n + 1);
     99     int xx = std::unique(X + 1, X + n + 1) - X - 1;
    100     for(int i = 1; i <= n; i++) {
    101         val[i] = std::lower_bound(X + 1, X + xx + 1, val[i]) - X;
    102         add(val[i], 1, xx, rt[i]);
    103         siz[i] = 1;
    104     }
    105     for(int i = 1; i <= m; i++) {
    106         scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].h);
    107     }
    108     std::sort(edge + 1, edge + m + 1);
    109     // build tree
    110     for(int i = 1; i <= m; i++) {
    111         int x = edge[i].x, y = edge[i].y;
    112         if(ufs::check(x, y)) {
    113             continue;
    114         }
    115         ++num;
    116         h[num] = edge[i].h;
    117         x = ufs::find(x);
    118         y = ufs::find(y);
    119         rt[num] = merge(rt[x], rt[y]);
    120         ufs::merge(num, x);
    121         ufs::merge(num, y);
    122         fa[x][0] = fa[y][0] = num;
    123         siz[num] = siz[x] + siz[y];
    124     }
    125     for(int i = 2; i <= num; i++) {
    126         pw[i] = pw[i >> 1] + 1;
    127     }
    128     for(int j = 1; j <= pw[num]; j++) {
    129         for(int i = 1; i <= num; i++) {
    130             fa[i][j] = fa[fa[i][j - 1]][j - 1];
    131         }
    132     }
    133  
    134     int lastans = 0;
    135     for(int i = 1, x, H, k; i <= q; i++) {
    136         scanf("%d%d%d", &x, &H, &k);
    137         if(lastans != -1) {x ^= lastans; H ^= lastans; k ^= lastans; }
    138         int y = getPos(x, H);
    139         if(siz[y] < k) puts("-1"), lastans = -1;
    140         else {
    141             lastans = X[ask(k, 1, xx, rt[y])];
    142             printf("%d
    ", lastans);
    143         }
    144     }
    145  
    146     return 0;
    147 }
    AC代码
  • 相关阅读:
    日区 Apple ID共享
    强大的视频跨平台视频处理软件
    百度网盘无限速
    App Store看片神器,请收好
    bootstrap 中这段代码 使bundles 失败
    C# EF中调用 存储过程并调回参数
    mvc 默认访问 Area 下控制器方法
    怎样用SQL语句查看查询的性能指标
    slice 定义和用法
    C# Regex类用法
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10415064.html
Copyright © 2020-2023  润新知