• 可持久化线段树初步


    可持久化线段树是可以查询历史版本的数据结构,比如说查询区间第k大的数,那么我们需要查询到1-r 和 1- (l - 1) 数据的分布情况,以完成查询。

      2015年11月25日

        模板题 poj2104

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define rep(i, a, b) for (int i = a; i <= b; i++)
     5 #define REP(i, a, b) for (int i = a; i < b; i++)
     6 #define drep(i, a, b) for (int i = a; i >= b; i--)
     7 #define mp make_pair
     8 #define pb push_back
     9 #define clr(x) memset(x, 0, sizeof(x))
    10 #define xx first
    11 #define yy second
    12 using namespace std;
    13 typedef long long i64;
    14 typedef pair<int, int> pii;
    15 const int inf = ~0U>>1;
    16 const i64 INF = ~0ULL >> 1;
    17 //*********************************
    18 
    19 const int maxn = 100005, maxm = 2060965;
    20 int Sum[maxm];
    21 int Lson[maxm], Rson[maxm];
    22 
    23 int read() {
    24     int l = 1, s = 0;
    25     char ch = getchar();
    26     while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); }
    27     while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); }
    28     return l * s;
    29 }
    30 
    31 int totnode;
    32 void build(int x, int &y, int l, int r, int v) {
    33     Sum[y = ++totnode] = Sum[x] + 1;
    34     if (l == r) return;
    35     int mid = l + r >> 1;
    36     if (v <= mid) {
    37         Rson[y] = Rson[x];
    38         build(Lson[x], Lson[y], l, mid, v);
    39     }
    40     else {
    41         Lson[y] = Lson[x];
    42         build(Rson[x], Rson[y], mid + 1, r, v);
    43     }
    44 }
    45 
    46 int query(int x, int y, int l, int r, int k) {
    47     if (l == r) return l;
    48     int mid = l + r >> 1, tmp = Sum[Lson[y]] - Sum[Lson[x]];
    49     if (tmp >= k) return query(Lson[x], Lson[y], l, mid, k);
    50     else return query(Rson[x], Rson[y], mid + 1, r, k - tmp);
    51 }
    52 
    53 int val[maxn], hsh[maxn], root[maxn];
    54 int main() {
    55     int n, m;
    56     n = read(), m = read();
    57     rep(i, 1, n) val[i] = read(), hsh[i] = val[i];
    58     sort(hsh + 1, hsh + 1 + n); int cd = unique(hsh + 1, hsh + 1 + n) - (hsh + 1);
    59     rep(i, 1, n) val[i] = lower_bound(hsh + 1, hsh + 1 + cd, val[i]) - hsh;
    60     
    61     int cnt = cd;
    62     for (int i = 1; i <= n; i++)
    63         build(root[i - 1], root[i], 1, cnt, val[i]);
    64    
    65     for (int i = 1; i <= m; i++) {
    66         int x, y, k; x = read(), y = read(), k = read();
    67         printf("%d
    ", hsh[query(root[x - 1], root[y], 1, cnt, k)]);
    68     }
    69 
    70     return 0;
    71 }
    View Code

        树上第k大 清橙1501 树

          以每一条链建立线段树,然后用第一个点减去lca加上第二个点减去lca上面那个点的值来查询,注意,线段树里开的是每个区间有多少个数。

      1 #include <bits/stdc++.h>
      2 #define rep(i, a, b) for (int i = a; i <= b; i++)
      3 #define REP(i, a, b) for (int i = a; i < b; i++)
      4 #define drep(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 i64;
     11 typedef pair<int, int> pii;
     12 const int inf = ~0U >> 1;
     13 const i64 INF = ~0ULL >> 1;
     14 //*****************************
     15 const int maxn = 200005, maxm = 1700005;
     16 struct Ed {
     17     int u, v, nx; Ed() {}
     18     Ed(int _u, int _v, int _nx) :
     19         u(_u), v(_v), nx(_nx) {}
     20 } E[maxn << 1];
     21 int G[maxn], ccnt;
     22 void addedge(int u, int v) {
     23     E[ccnt] = Ed(u, v, G[u]);
     24     G[u] = ccnt++;
     25 }
     26 int dep[maxn], fa[maxn][18];
     27 bool vis[maxn];
     28 int val[maxn];
     29 void build_lca(int x) {
     30     vis[x] = 1;
     31     rep(i, 1, 17) {
     32         if (1 << i > dep[x]) break;
     33         fa[x][i] = fa[fa[x][i - 1]][i - 1];
     34     }
     35     for (int i = G[x]; i != -1; i = E[i].nx) if (!vis[E[i].v]) {
     36         dep[E[i].v] = dep[x] + 1;
     37         fa[E[i].v][0] = x;
     38         build_lca(E[i].v);
     39     }
     40 }
     41 int ask(int l, int r) {
     42     if (dep[l] < dep[r]) swap(l, r);
     43     int t = dep[l] - dep[r];
     44     drep(i, 17, 0) {
     45         if (t & 1 << i) {
     46             l = fa[l][i];
     47         }
     48     }
     49     if (l == r) return l;
     50     drep(i, 17, 0) {
     51         if (fa[l][i] != fa[r][i]) {
     52             l = fa[l][i], r = fa[r][i];
     53         }
     54     }
     55     return fa[l][0];
     56 }
     57 int Sum[maxm], Lson[maxm], Rson[maxm], ndtot, root[maxm];
     58 void build(int x, int &y, int l, int r, int v) {
     59     Sum[y = ++ndtot] = Sum[x] + 1;
     60     if (l == r) return;
     61     int mid = l + r >> 1;
     62     if (v <= mid) {
     63         Rson[y] = Rson[x];
     64         build(Lson[x], Lson[y], l, mid, v);
     65     }
     66     else {
     67         Lson[y] = Lson[x];
     68         build(Rson[x], Rson[y], mid + 1, r, v);
     69     }
     70 }
     71 int cnt;
     72 void dfs(int x, int father) {
     73     build(root[father], root[x], 1, cnt, val[x]);
     74     for (int i = G[x]; i != -1; i = E[i].nx) 
     75         if (E[i].v != father) dfs(E[i].v, x);
     76 }
     77 int query(int x1, int y1, int x2, int y2, int l, int r, int k) {
     78     if (l == r) return l;
     79     int mid = l + r >> 1, tmp = Sum[Lson[x1]] - Sum[Lson[y1]] + Sum[Lson[x2]] - Sum[Lson[y2]];
     80     if (tmp >= k) return query(Lson[x1], Lson[y1], Lson[x2], Lson[y2], l, mid, k);
     81     else return query(Rson[x1], Rson[y1], Rson[x2], Rson[y2], mid + 1, r, k - tmp);
     82 }
     83 int solve(int x, int y, int lca, int op) {
     84     int st1 = lca, st2 = fa[lca][0];
     85     int tot = Sum[root[x]] - Sum[root[st1]] + Sum[root[y]] - Sum[root[st2]];
     86     int k;
     87     if (op == 1) k = 1;
     88     else if (op == 2) k = tot;
     89     else { k = tot >> 1; k++; }
     90     return query(root[x], root[st1], root[y], root[st2], 1, cnt, k);
     91 }
     92 int read() {
     93     int l = 1, s = 0;
     94     char ch = getchar();
     95     while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); }
     96     while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); }
     97     return l * s;
     98 }
     99 int hsh[maxn];
    100 int main() {
    101     int n, m;
    102     scanf("%d%d", &n, &m);
    103     memset(G, -1, sizeof(G));
    104     rep(i, 1, n) val[i] = hsh[i] = read();
    105     sort(hsh + 1, hsh + 1 + n); int cd = unique(hsh + 1, hsh + 1 + n) - (hsh + 1);
    106     rep(i, 1, n) val[i] = lower_bound(hsh + 1, hsh + 1 + cd, val[i]) - hsh;
    107     REP(i, 1, n) {
    108         int x, y;
    109         x = read(), y = read(), addedge(x, y), addedge(y, x);
    110     }
    111     build_lca(1);
    112     cnt = cd;
    113     dfs(1, 0);
    114     rep(i, 1, m) {
    115         int op, x, y;
    116         op = read(), x = read(), y = read();
    117         int t = ask(x, y);
    118         printf("%d
    ", hsh[solve(x, y, t, op)]);
    119     }
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    看懂Oracle执行计划
    pl/sql编译存储过程卡住的解决方法
    ORA-00604的解决方法
    ORACLE SYNONYM详解
    Oracle 用户权限管理方法
    “ORA-06550: 第 1 行, 第 7 列”解决方法
    oracle 存储过程给另一个用户的权限问题
    Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile
    eclipse maven maven-compiler-plugin 报错 完全解决
    如何用git把本地代码上传到github
  • 原文地址:https://www.cnblogs.com/y7070/p/4999480.html
Copyright © 2020-2023  润新知