zoukankan      html  css  js  c++  java
  • 求LCA练习+部分算法复习 2017.1.22


      第一题就LCA即可。不过推荐用Tarjan(最快,常数很小)。然后Tarjan的时候顺便就出一个dist[i],表示i节点到根节点的距离。求出了LCA,那么两点间的距离就为dist[u] + dist[v] - 2 * dist[lca]。

    Code

      1 #include<iostream>
      2 #include<sstream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cctype>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 #include<stack>
     12 #include<vector>
     13 #include<algorithm>
     14 #ifndef    WIN32
     15 #define    AUTO "%I64d"
     16 #else
     17 #define AUTO "%lld"
     18 #endif
     19 using namespace std;
     20 typedef bool boolean;
     21 #define smin(a, b) (a) = min((a), (b))
     22 #define smax(a, b) (a) = max((a), (b))
     23 template<typename T>
     24 inline void readInteger(T& u){
     25     char x;
     26     int aFlag = 1;
     27     while(!isdigit((x = getchar())) && x != '-');
     28     if(x == '-'){
     29         aFlag = -1;
     30         x = getchar();
     31     }
     32     for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0');
     33     ungetc(x, stdin);
     34     u *= aFlag;
     35 }
     36 
     37 typedef class Edge {
     38     public:
     39         int end;
     40         int next;
     41         int w;
     42         Edge(const int end = 0, const int next = 0, const int w = 0):end(end), next(next), w(w){        }
     43 }Edge;
     44 
     45 typedef class MapManager{
     46     public:
     47         int ce;
     48         Edge* edges;
     49         int* h;
     50         MapManager():ce(0), edges(NULL), h(NULL){        }
     51         MapManager(int points, int limit):ce(0){
     52             edges = new Edge[(const int)(limit + 1)];
     53             h = new int[(const int)(points + 1)];
     54             memset(h, 0, sizeof(int) * (points + 1));
     55         }
     56         inline void addEdge(int from, int end, int w){
     57             edges[++ce] = Edge(end, h[from], w);
     58             h[from] = ce;
     59         }
     60         inline void addDoubleEdge(int from, int end, int w){
     61             addEdge(from, end, w);
     62             addEdge(end, from, w);
     63         }
     64         Edge& operator [](int pos){
     65             return edges[pos];
     66         }
     67 }MapManager;
     68 #define m_begin(g, i) (g).h[(i)]
     69 
     70 typedef class union_found{
     71     public:
     72         int *f;
     73         union_found():f(NULL) {}
     74         union_found(int points) {
     75             f = new int[(const int)(points + 1)];
     76         }
     77         int find(int x) {
     78             if(f[x] != x)    return f[x] = find(f[x]);
     79             return f[x];
     80         }
     81         void unit(int fa, int so) {
     82             int ffa = find(fa);
     83             int fso = find(so);
     84             f[fso] = ffa;
     85         }
     86         int& operator [](int pos){
     87             return f[pos];
     88         }
     89 }union_found;
     90 
     91 int n, m;
     92 MapManager g;
     93 MapManager q;
     94 int *results;
     95 boolean* enable;
     96 int *querya, *queryb;
     97 union_found uf;
     98 boolean* visited;
     99 int* dist;
    100 
    101 inline void init(){
    102     readInteger(n);
    103     g = MapManager(n, 2 * n);
    104     for(int i = 1, a, b, c; i < n; i++){
    105         readInteger(a);
    106         readInteger(b);
    107         readInteger(c);
    108         g.addDoubleEdge(a, b, c);
    109     }
    110     readInteger(m);
    111     q = MapManager(n, 2 * m);
    112     querya = new int[(const int)(m + 1)];
    113     queryb = new int[(const int)(m + 1)];
    114     results = new int[(const int)(m + 1)];
    115     enable = new boolean[(const int)(m + 1)];
    116     dist = new int[(const int)(n + 1)];
    117     uf = union_found(n);
    118     visited = new boolean[(const int)(n + 1)];
    119     memset(visited, false, sizeof(boolean) * (n + 1));
    120     memset(enable, true, sizeof(boolean) * (m + 1));
    121     for(int i = 1; i <= m; i++){
    122         readInteger(querya[i]);
    123         readInteger(queryb[i]);
    124         q.addDoubleEdge(querya[i], queryb[i], i);
    125     }
    126     dist[1] = 0;
    127 }
    128 
    129 void tarjan(int node, int f){
    130     uf[node] = node;
    131     visited[node] = true;
    132     for(int i = m_begin(g, node); i != 0; i = g[i].next){
    133         int& e = g[i].end;
    134         if(e == f)    continue;
    135         dist[e] = dist[node] + g[i].w;
    136         tarjan(e, node);
    137         uf[e] = node;
    138     }
    139     for(int i = m_begin(q, node); i != 0; i = q[i].next) {
    140         int& e = q[i].end;
    141         if(visited[e] && enable[q[i].w]){
    142             int lca = uf.find(e);
    143             results[q[i].w] = lca;
    144             enable[q[i].w] = false;
    145         }
    146     }
    147 }
    148 
    149 inline void solve(){
    150     tarjan(1, 0);
    151     for(int i = 1; i <= m; i++){
    152         int dis = dist[querya[i]] + dist[queryb[i]] - 2 * dist[results[i]];
    153         printf("%d
    ", dis);
    154     }
    155 }
    156 
    157 int main(){
    158     freopen("distance.in", "r", stdin);
    159     freopen("distance.out", "w", stdout);
    160     init();
    161     solve();
    162     return 0;
    163 }
    distance (Tarjan)
      1 #include<iostream>
      2 #include<sstream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cctype>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 #include<stack>
     12 #include<vector>
     13 #include<algorithm>
     14 #ifndef    WIN32
     15 #define    AUTO "%I64d"
     16 #else
     17 #define AUTO "%lld"
     18 #endif
     19 using namespace std;
     20 typedef bool boolean;
     21 #define smin(a, b) (a) = min((a), (b))
     22 #define smax(a, b) (a) = max((a), (b))
     23 template<typename T>
     24 inline void readInteger(T& u){
     25     char x;
     26     int aFlag = 1;
     27     while(!isdigit((x = getchar())) && x != '-');
     28     if(x == '-'){
     29         aFlag = -1;
     30         x = getchar();
     31     }
     32     for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0');
     33     ungetc(x, stdin);
     34     u *= aFlag;
     35 }
     36 
     37 template<typename T>class Matrix{
     38     public:
     39         T *p;
     40         int lines;
     41         int rows;
     42         Matrix():p(NULL){    }
     43         Matrix(int rows, int lines):lines(lines), rows(rows){
     44             p = new T[(lines * rows)];
     45         }
     46         T* operator [](int pos){
     47             return (p + pos * lines);
     48         }
     49 };
     50 #define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows)
     51 
     52 ///map template starts
     53 typedef class Edge{
     54     public:
     55         int end;
     56         int next;
     57         int w;
     58         Edge(const int end = 0, const int next = 0, const int w = 0):end(end), next(next), w(w){}
     59 }Edge;
     60 typedef class MapManager{
     61     public:
     62         int ce;
     63         int *h;
     64         int w;
     65         Edge *edge;
     66         MapManager(){}
     67         MapManager(int points, int limit):ce(0){
     68             h = new int[(const int)(points + 1)];
     69             edge = new Edge[(const int)(limit + 1)];
     70             memset(h, 0, sizeof(int) * (points + 1));
     71         }
     72         inline void addEdge(int from, int end, int w){
     73             edge[++ce] = Edge(end, h[from], w);
     74             h[from] = ce;
     75         }
     76         inline void addDoubleEdge(int from, int end, int w){
     77             addEdge(from, end, w);
     78             addEdge(end, from, w);
     79         }
     80         Edge& operator[] (int pos) {
     81             return edge[pos];
     82         }
     83 }MapManager;
     84 #define m_begin(g, i) (g).h[(i)]
     85 ///map template ends
     86 
     87 int n, m;
     88 int cnt = 0;
     89 Matrix<int> st;
     90 int* seq;
     91 int* dep;
     92 int *app;
     93 MapManager g;
     94 int *mlog2;
     95 long long *dist;
     96 
     97 inline void init() {
     98     readInteger(n);
     99     g = MapManager(n, 2  * n);
    100     seq = new int[(const int)(2 * n + 1)];
    101     dist = new long long[(const int)(n + 1)];
    102     dep = new int[(const int)(n + 1)];
    103     app = new int[(const int)(n + 1)];
    104     for(int i = 1, a, b, w; i < n; i++){
    105         readInteger(a);
    106         readInteger(b);
    107         readInteger(w);
    108         g.addDoubleEdge(a, b, w);
    109     }
    110     dist[1] = 0;
    111     dep[0] = 0;
    112 }
    113 
    114 void dfs(int node, int f) {
    115     seq[++cnt] = node;
    116     app[node] = cnt;
    117     dep[node] = dep[f] + 1;
    118     for(int i = m_begin(g, node); i != 0; i = g[i].next) {
    119         int& e = g[i].end;
    120         if(e == f)    continue;
    121         dist[e] = dist[node] + g[i].w;
    122         dfs(e, node);
    123         seq[++cnt] = node;
    124     }
    125 }
    126 
    127 inline void init_log() {
    128     mlog2 = new int[(const int)(2 * n + 1)];
    129     mlog2[1] = 0;
    130     for(int i = 2; i <= 2 * n; i++)
    131         mlog2[i] = mlog2[i / 2] + 1; 
    132 }
    133 
    134 inline void init_st() {
    135     init_log();
    136     st = Matrix<int>(cnt, mlog2[cnt] + 1);
    137     for(int i = 1; i <= cnt; i++)
    138         st[i][0] = seq[i];
    139     for(int j = 1; j <= mlog2[cnt]; j++)
    140         for(int i = 1; i + (1 << j) - 1 <= cnt; i++)
    141             st[i][j] = (dep[st[i][j - 1]] < dep[st[i + (1 << (j - 1))][j - 1]]) ? (st[i][j - 1]) : (st[i + (1 << (j - 1))][j - 1]);
    142 }
    143 
    144 inline int lca(int a, int b) {
    145     if(app[a] > app[b])    swap(a, b);
    146     int pos = mlog2[app[b] - app[a] + 1];
    147     int u = st[app[a]][pos];
    148     int v = st[app[b] - (1 << pos) + 1][pos];
    149     return (dep[u] > dep[v]) ? (v) : (u);
    150 }
    151 
    152 long long dis;
    153 inline void solve() {
    154     readInteger(m);
    155     for(int i = 1, a, b; i <= m; i++){
    156         readInteger(a);
    157         readInteger(b);
    158         int l = lca(a, b);
    159         dis = dist[a] + dist[b] - 2 * dist[l];
    160         printf(AUTO"
    ", dis);
    161     }
    162 }
    163 
    164 int main() {
    165     freopen("distance.in", "r", stdin);
    166     freopen("distance.out", "w", stdout);
    167     init();
    168     dfs(1, 0);
    169     init_st();
    170     solve();
    171     return 0;
    172 }
    distance (st table)

      话说ST表在n,q都尽量大的情况下,其他数据随机,竟然平均一个点比Tarjan 0.05s左右。(也有可能是我的st表写得比较丑)



      第二题还是一遍dfs序,接着可以开开心心地放线段树去装逼了。(然而我把某些"+="写成了"=",于是AK又没有了。。一定是写这道题和检查的时候头脑都不清醒)

    Code

      1 #include<iostream>
      2 #include<sstream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cctype>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 #include<stack>
     12 #include<vector>
     13 #include<algorithm>
     14 #ifdef    WIN32
     15 #define    AUTO "%I64d"
     16 #else
     17 #define AUTO "%lld"
     18 #endif
     19 using namespace std;
     20 typedef bool boolean;
     21 #define smin(a, b) (a) = min((a), (b))
     22 #define smax(a, b) (a) = max((a), (b))
     23 template<typename T>
     24 inline void readInteger(T& u){
     25     char x;
     26     int aFlag = 1;
     27     while(!isdigit((x = getchar())) && x != '-');
     28     if(x == '-'){
     29         aFlag = -1;
     30         x = getchar();
     31     }
     32     for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0');
     33     ungetc(x, stdin);
     34     u *= aFlag;
     35 }
     36 
     37 typedef class Edge {
     38     public:
     39         int end;
     40         int next;
     41         Edge(const int end = 0, const int next = 0):end(end), next(next){        }
     42 }Edge;
     43 
     44 typedef class MapManager{
     45     public:
     46         int ce;
     47         Edge* edges;
     48         int* h;
     49         MapManager():ce(0), edges(NULL), h(NULL){        }
     50         MapManager(int points, int limit):ce(0){
     51             edges = new Edge[(const int)(limit + 1)];
     52             h = new int[(const int)(points + 1)];
     53             memset(h, 0, sizeof(int) * (points + 1));
     54         }
     55         inline void addEdge(int from, int end){
     56             edges[++ce] = Edge(end, h[from]);
     57             h[from] = ce;
     58         }
     59         inline void addDoubleEdge(int from, int end){
     60             addEdge(from, end);
     61             addEdge(end, from);
     62         }
     63         Edge& operator [](int pos){
     64             return edges[pos];
     65         }
     66 }MapManager;
     67 #define m_begin(g, i) (g).h[(i)]
     68 
     69 typedef class SegTreeNode{
     70     public:
     71         long long sum;
     72         int l, r;
     73         SegTreeNode *left, *right;
     74         long long lazy;
     75         SegTreeNode(int l, int r):l(l), r(r), sum(0), lazy(0), left(NULL), right(NULL){        }
     76         
     77         inline void pushUp(){
     78             this->sum = left->sum + right->sum;
     79         }
     80         
     81         inline void pushDown(){
     82             left->lazy += lazy;
     83             right->lazy += lazy;
     84             left->sum += lazy * (left->r - left->l + 1);
     85             right->sum += lazy * (right->r - right->l + 1);
     86             lazy = 0;
     87         }
     88 }SegTreeNode;
     89 
     90 typedef class SegTree {
     91     public:
     92         SegTreeNode* root;
     93         SegTree():root(NULL){    }
     94         SegTree(int size) {
     95             build(root, 1, size);
     96         }
     97         
     98         void build(SegTreeNode*& node, int l, int r){
     99             node = new SegTreeNode(l, r);
    100             if(l == r)    return;
    101             int mid = (l + r) >> 1;
    102             build(node->left, l, mid);
    103             build(node->right, mid + 1, r);
    104         }
    105         
    106         void update(SegTreeNode*& node, int l, int r, int from, int end, long long val){
    107             if(l == from && r == end){
    108                 node->sum += val * (r - l + 1);
    109                 node->lazy += val;
    110                 return;
    111             }
    112             if(node->lazy)    node->pushDown();
    113             int mid = (l + r) >> 1;
    114             if(end <= mid)    update(node->left, l, mid, from, end, val);
    115             else if(from > mid)    update(node->right, mid + 1, r, from, end, val);
    116             else{
    117                 update(node->left, l, mid, from, mid, val);
    118                 update(node->right, mid + 1, r, mid + 1, end, val);
    119             }
    120             node->pushUp();
    121         }
    122         
    123         long long query(SegTreeNode*& node, int index){
    124             if(node->l == index && node->r == index){
    125                 return node->sum;
    126             }
    127             if(node->lazy)    node->pushDown();
    128             int mid = (node->l + node->r) >> 1;
    129             if(index <= mid)    return query(node->left, index);
    130             return query(node->right, index);
    131         }
    132         
    133         long long query(SegTreeNode*& node, int from, int end){
    134             if(node->l == from && node->r == end){
    135                 return node->sum;
    136             }
    137             if(node->lazy)    node->pushDown();
    138             int mid = (node->l + node->r) >> 1;
    139             if(end <= mid)    return query(node->left, from, end);
    140             if(from > mid)    return query(node->right, from, end);
    141             return query(node->left, from, mid) + query(node->right, mid + 1, end);
    142         }
    143 }SegTree;
    144 
    145 int n, m;
    146 SegTree st;
    147 int cnt = 0;
    148 int* visitID;
    149 int* exitID;
    150 MapManager g;
    151 
    152 inline void init() {
    153     readInteger(n);
    154     g = MapManager(n, 2 * n);
    155     for(int i = 1, a, b; i < n; i++){
    156         readInteger(a);
    157         readInteger(b);
    158         g.addDoubleEdge(a, b);
    159     }
    160     visitID = new int[(const int)(n + 1)];
    161     exitID = new int[(const int)(n + 1)];
    162 }
    163 
    164 void dfs(int node, int last){
    165     visitID[node] = ++cnt;
    166     for(int i = m_begin(g, node); i != 0; i = g[i].next) {
    167         int& e = g[i].end;
    168         if(e == last)    continue;
    169         dfs(e, node);
    170     }
    171     exitID[node] = cnt;
    172 }
    173 
    174 inline void solve() {
    175     dfs(1, 0);
    176     readInteger(m);
    177     st = SegTree(n);
    178     char cmd[10];
    179     int a, b;
    180     while(m--) {
    181         scanf("%s", cmd);
    182         readInteger(a);
    183         if(cmd[0] == 'g') {
    184             readInteger(b);
    185             st.update(st.root, 1, n, visitID[a], exitID[a], b);
    186         }else if(cmd[0] == 's'){
    187             long long res = st.query(st.root, visitID[a]);
    188             printf(AUTO"
    ", res);
    189         }else if(cmd[0] == 'a'){
    190             long long res = st.query(st.root, visitID[a], exitID[a]);
    191             printf(AUTO"
    ", res);
    192         }
    193     }
    194 }
    195 
    196 int main() {
    197     freopen("redpacket.in", "r", stdin);
    198     freopen("redpacket.out", "w", stdout);
    199     init();
    200     solve();
    201     return 0;
    202 }



      一看就发现是专为值域线段树设置的裸题。

    Code

      1 #include<iostream>
      2 #include<sstream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cctype>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 #include<stack>
     12 #include<vector>
     13 #include<algorithm>
     14 #ifndef    WIN32
     15 #define    AUTO "%I64d"
     16 #else
     17 #define AUTO "%lld"
     18 #endif
     19 using namespace std;
     20 typedef bool boolean;
     21 #define smin(a, b) (a) = min((a), (b))
     22 #define smax(a, b) (a) = max((a), (b))
     23 template<typename T>
     24 inline void readInteger(T& u){
     25     char x;
     26     int aFlag = 1;
     27     while(!isdigit((x = getchar())) && x != '-');
     28     if(x == '-'){
     29         aFlag = -1;
     30         x = getchar();
     31     }
     32     for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0');
     33     ungetc(x, stdin);
     34     u *= aFlag;
     35 }
     36 
     37 typedef class SegTreeNode {
     38     public:
     39         int s;
     40         SegTreeNode* left, *right;
     41         
     42         inline void pushUp(){
     43             s = left->s + right->s;
     44         }
     45 }SegTreeNode;
     46 
     47 typedef class SegTree {
     48     public:
     49         int lb, rb;
     50         SegTreeNode* root;
     51         SegTree():root(NULL) {        }
     52         SegTree(int lb, int rb, int* list):lb(lb), rb(rb){
     53             build(root, 1, rb - lb + 1, list);
     54         }
     55         
     56         void build(SegTreeNode*& node, int l, int r, int* list){
     57             node = new SegTreeNode();
     58             if(l == r){
     59                 node->s = list[l];
     60                 return;
     61             }
     62             int mid = (l + r) >> 1;
     63             build(node->left, l, mid, list);
     64             build(node->right, mid + 1, r, list);
     65             node->pushUp();
     66         }
     67         
     68         void update(SegTreeNode*& node, int l, int r, int index, int val){
     69             if(l == index && r == index){
     70                 node->s += val;
     71                 smax(node->s, 0);
     72                 return;
     73             }
     74             int mid = (l + r) >> 1;
     75             if(index <= mid)    update(node->left, l, mid, index, val);
     76             else update(node->right, mid + 1, r, index, val);
     77             node->pushUp();
     78         }
     79         
     80         int findKth(SegTreeNode*& node, int l, int r, int k){
     81             if(l == r)    return l + lb - 1;
     82             int ls = node->left->s;
     83             int mid = (l + r) >> 1;
     84             if(k <= ls)    return findKth(node->left, l, mid, k);            
     85             return findKth(node->right, mid + 1, r, k - ls);
     86         }
     87 }SegTree;
     88 
     89 int n;
     90 int lb, rb;
     91 int* list;
     92 SegTree st;
     93 inline void init() {
     94     readInteger(lb);
     95     readInteger(rb);
     96     list = new int[(const int)(rb - lb + 2)];
     97     for(int i = lb; i <= rb; i++){
     98         readInteger(list[i - lb + 1]);
     99     }
    100     st = SegTree(lb, rb, list);
    101 }
    102 
    103 inline void solve() {
    104     const int L = rb - lb + 1;
    105     readInteger(n);
    106     char cmd[10];
    107     int a;
    108     while(n--) {
    109         scanf("%s", cmd);
    110         readInteger(a);
    111         if(cmd[0] == 'a'){
    112             st.update(st.root, 1, L, a - lb + 1, 1);
    113         }else if(cmd[0] == 'd'){
    114             st.update(st.root, 1, L, a - lb + 1, -1);
    115         }else{
    116             int res = st.findKth(st.root, 1, L, a);
    117             printf("%d
    ", res);
    118         }
    119     }
    120 }
    121 
    122 int main(){
    123     freopen("kth.in", "r", stdin);
    124     freopen("kth.out", "w", stdout);
    125     init();
    126     solve();
    127     return 0;
    128 }
    值域线段树

      然后我还用了替罪羊树(然而发现,都快成普通的二叉搜索树了),O(n)离线建完整棵树,插入删除都不需要重构,即使为count为0也不管(删掉它需要花费更过的时间)。不过测了后发现,略微比值域线段树快一点,应该是因为各种操作在中途完成就开始返回了。

    Code

      1 #include<iostream>
      2 #include<sstream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cctype>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 #include<stack>
     12 #include<vector>
     13 #include<algorithm>
     14 #ifndef    WIN32
     15 #define    AUTO "%I64d"
     16 #else
     17 #define AUTO "%lld"
     18 #endif
     19 using namespace std;
     20 typedef bool boolean;
     21 #define smin(a, b) (a) = min((a), (b))
     22 #define smax(a, b) (a) = max((a), (b))
     23 template<typename T>
     24 inline void readInteger(T& u){
     25     char x;
     26     int aFlag = 1;
     27     while(!isdigit((x = getchar())) && x != '-');
     28     if(x == '-'){
     29         aFlag = -1;
     30         x = getchar();
     31     }
     32     for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0');
     33     ungetc(x, stdin);
     34     u *= aFlag;
     35 }
     36 
     37 template<typename T>
     38 class ScapegoatTreeNode {
     39     public:
     40         T val;
     41         int count;
     42         int size;
     43         ScapegoatTreeNode* next[2];
     44         ScapegoatTreeNode():count(1), size(1){
     45             memset(next, 0, sizeof(next));
     46         }
     47         ScapegoatTreeNode(T val):val(val), count(1), size(1){
     48             memset(next, 0, sizeof(next));
     49         }
     50         
     51         inline void maintain() {
     52             size = count;
     53             for(int i = 0; i < 2; i++)
     54                 if(next[i] != NULL)
     55                     size += next[i]->size;
     56         }
     57         
     58         inline void addCount(int c){
     59             if(count == 0 && c < 0)    return;
     60             size += c, count += c;
     61         }
     62         
     63         inline int cmp(T x){
     64             if(val == x)    return -1;
     65             return (x < val) ? (0) : (1);
     66         }
     67 };
     68 
     69 template<typename T>
     70 class ScapegoatTree {
     71     protected:
     72         static void insert(ScapegoatTreeNode<T>*& node, T val){
     73             if(node == NULL){
     74                 node = new ScapegoatTreeNode<T>(val);
     75                 return;
     76             }
     77             int d = node->cmp(val);
     78             if(d == -1){
     79                 node->addCount(1);
     80                 return;
     81             }
     82             insert(node->next[d], val);
     83             node->maintain();
     84         }
     85         
     86         static boolean remove(ScapegoatTreeNode<T>*& node, T val){
     87             if(node == NULL)    return false;
     88             int d = node->cmp(val);
     89             if(d == -1){
     90                 node->addCount(-1);
     91                 return true;
     92             }
     93             boolean res = remove(node->next[d], val);
     94             if(res)    node->maintain();
     95             return res;
     96         }
     97         
     98         static ScapegoatTreeNode<T>* findKth(ScapegoatTreeNode<T>*& node, int k){
     99             int ls = (node->next[0] == NULL) ? (0) : (node->next[0]->size);
    100             if(k >= ls + 1 && k <= ls + node->count)    return node;
    101             if(k <= ls)    return findKth(node->next[0], k);
    102             return findKth(node->next[1], k - ls - node->count);
    103         }
    104     public:
    105         ScapegoatTreeNode<T>* root;
    106         vector<ScapegoatTreeNode<T>*> lis;
    107         
    108         ScapegoatTree():root(NULL){        }
    109         
    110         ScapegoatTreeNode<T>* rebuild(int l, int r){
    111             if(l > r)    return NULL;
    112             int mid = (l + r) >> 1;
    113             ScapegoatTreeNode<T>*& node = lis[mid];
    114             node->next[0] = rebuild(l, mid - 1);
    115             node->next[1] = rebuild(mid + 1, r);
    116             node->maintain();
    117             return node;
    118         }
    119         
    120         void rebuild(ScapegoatTreeNode<T>*& node, ScapegoatTreeNode<T>*& f){
    121             lis.clear();
    122             travel(node);
    123             int d = -1;
    124             if(f != NULL)    d = f->cmp(node->val);
    125             ScapegoatTreeNode<T>* res = rebuild(0, lis.size() - 1);
    126             if(d != -1)        f->next[d] = res;
    127             else root = res;
    128         }
    129         
    130         void insert(T val){
    131             insert(root, val);
    132         }
    133         
    134         void remove(T val){
    135             remove(root, val);
    136         }
    137         
    138         ScapegoatTreeNode<T>* findKth(int k){
    139             return findKth(root, k);
    140         }
    141 };
    142 
    143 int n;
    144 int lb, rb;
    145 ScapegoatTree<int> s;
    146 
    147 inline void init() {
    148     readInteger(lb);
    149     readInteger(rb);
    150     for(int i = lb; i <= rb; i++){
    151         ScapegoatTreeNode<int>* node = new ScapegoatTreeNode<int>(i);
    152         readInteger(node->count);
    153         node->maintain();
    154         s.lis.push_back(node);
    155     }
    156     s.root = s.rebuild(0, s.lis.size() - 1);
    157 }
    158 
    159 inline void solve() {
    160     readInteger(n);
    161     char cmd[10];
    162     int a;
    163     while(n--) {
    164         scanf("%s", cmd);
    165         readInteger(a);
    166         if(cmd[0] == 'a'){
    167             s.insert(a);
    168         }else if(cmd[0] == 'd'){
    169             s.remove(a);
    170         }else{
    171             ScapegoatTreeNode<int>* node = s.findKth(a);
    172             printf("%d
    ", node->val);
    173         }
    174     }
    175 }
    176 
    177 int main(){
    178     freopen("kth.in", "r", stdin);
    179     freopen("kth.out", "w", stdout);
    180     init();
    181     solve();
    182     return 0;
    183 }
    替罪羊树
  • 相关阅读:
    根据输入的个数,打印每行做多输出3个的for循环
    在启动页面后面再加载一个广告页,可以定制动画等
    frame.size.height无法直接赋值问题
    iOS开发远程推送
    iOS——UIKeyboardWillShowNotification 监听键盘高度变化
    iOS 浅谈本地通知 UILocalNotification
    iOS中assign、copy 、retain等关键字的含义
    GCD
    xocde快速定位崩溃代码
    关于xcode打包app
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6341488.html
Copyright © 2011-2022 走看看