• 树套树专题


    对数据结构的不熟练

    3196: Tyvj 1730 二逼平衡树

    题目链接

    尝试一下树状数组套主席树的写法。

    小细节没有重视:为了方便起见,一般我们写getRank(x)求的都是<x的数个数。求前驱后继时需要稍微留点心。

      1 #include<bits/stdc++.h>
      2 const int maxn = 50035;
      3 const int maxNode = 5000035;
      4 const int INF = 2147483647;
      5 
      6 struct node
      7 {
      8     int val,l,r;
      9 }f[maxNode];
     10 struct QRs
     11 {
     12     int opt,l,r,k;
     13 }qr[maxn];
     14 int n,m,rt[maxn],v[maxn],tot,cnt[maxn<<1];
     15 int cntl,cntr,L[maxn],R[maxn];
     16 
     17 int read()
     18 {
     19     char ch = getchar();
     20     int num = 0, fl = 1;
     21     for (; !isdigit(ch); ch=getchar())
     22         if (ch=='-') fl = -1;
     23     for (; isdigit(ch); ch=getchar())
     24         num = (num<<1)+(num<<3)+ch-48;
     25     return num*fl;
     26 }
     27 void update(int &rt, int l, int r, int c, int d)
     28 {
     29     if (!rt) rt = ++tot;
     30     f[rt].val += d;
     31     if (l==r) return;
     32     int mid = (l+r)>>1;
     33     if (c <= mid) update(f[rt].l, l, mid, c, d);
     34     else update(f[rt].r, mid+1, r, c, d);
     35 }
     36 int rank(int L, int R, int c)
     37 {
     38     int ret = 0, mid;
     39     for (int i=R; i; i-=i&-i)
     40     {
     41         int u = rt[i], l = 1, r = cnt[0];
     42         while (f[u].val&&l!=r)
     43         {
     44             mid = (l+r)>>1;
     45             if (c <= mid) r = mid, u = f[u].l;
     46             else l = mid+1, ret += f[f[u].l].val, u = f[u].r;
     47         }
     48     }
     49     for (int i=L-1; i; i-=i&-i)
     50     {
     51         int u = rt[i], l = 1, r = cnt[0];
     52         while (f[u].val&&l!=r)
     53         {
     54             mid = (l+r)>>1;
     55             if (c <= mid) r = mid, u = f[u].l;
     56             else l = mid+1, ret -= f[f[u].l].val, u = f[u].r;
     57         }
     58     }
     59     return ret;
     60 }
     61 int ask(int l, int r, int k)
     62 {
     63     if (l==r) return l;
     64     int mid = (l+r)>>1, val = 0;
     65     for (int i=1; i<=cntr; i++) val += f[f[R[i]].l].val;
     66     for (int i=1; i<=cntl; i++) val -= f[f[L[i]].l].val;
     67     if (k <= val){
     68         for (int i=1; i<=cntl; i++) L[i] = f[L[i]].l;
     69         for (int i=1; i<=cntr; i++) R[i] = f[R[i]].l;
     70         return ask(l, mid, k);
     71     }else{
     72         for (int i=1; i<=cntl; i++) L[i] = f[L[i]].r;
     73         for (int i=1; i<=cntr; i++) R[i] = f[R[i]].r;
     74         return ask(mid+1, r, k-val);
     75     }
     76 }
     77 void getRank(int l, int r, int k)
     78 {
     79     for (int j=l-1; j; j-=j&-j) L[++cntl] = rt[j];
     80     for (int j=r; j; j-=j&-j) R[++cntr] = rt[j];
     81     printf("%d
    ",cnt[ask(1, cnt[0], k)]);
     82 }
     83 int main()
     84 {
     85     n = read(), m = read();
     86     for (int i=1; i<=n; i++) v[i] = cnt[++cnt[0]] = read();
     87     for (int i=1; i<=m; i++)
     88     {
     89         qr[i].opt = read();
     90         if (qr[i].opt==3) qr[i].l = read();
     91         else qr[i].l = read(), qr[i].r = read();
     92         qr[i].k = cnt[++cnt[0]] = read();
     93     }
     94     cnt[++cnt[0]] = INF, cnt[++cnt[0]] = -INF;
     95     std::sort(cnt+1, cnt+cnt[0]+1);
     96     cnt[0] = std::unique(cnt+1, cnt+cnt[0]+1)-cnt-1;
     97     for (int i=1; i<=n; i++)
     98     {
     99         v[i] = std::lower_bound(cnt+1, cnt+cnt[0]+1, v[i])-cnt;
    100         for (int p=i; p<=n; p+=p&-p)
    101             update(rt[p], 1, cnt[0], v[i], 1);
    102     }
    103     for (int opt, i=1; i<=m; i++)
    104     {
    105         opt = qr[i].opt, cntl = cntr = 0;
    106         if (opt!=2) qr[i].k = std::lower_bound(cnt+1, cnt+cnt[0]+1, qr[i].k)-cnt;
    107         if (opt==1) printf("%d
    ",rank(qr[i].l, qr[i].r, qr[i].k)+1);
    108         if (opt==2){
    109             getRank(qr[i].l, qr[i].r, qr[i].k);
    110         }
    111         if (opt==3){
    112             for (int p=qr[i].l; p<=n; p+=p&-p)
    113                 update(rt[p], 1, cnt[0], v[qr[i].l], -1);
    114             v[qr[i].l] = qr[i].k;
    115             for (int p=qr[i].l; p<=n; p+=p&-p)
    116                 update(rt[p], 1, cnt[0], qr[i].k, 1);
    117         }
    118         if (opt==4){
    119             int rkx = rank(qr[i].l, qr[i].r, qr[i].k);
    120             if (!rkx) printf("%d
    ",-INF);
    121             else getRank(qr[i].l, qr[i].r, rkx);
    122         }
    123         if (opt==5){
    124             int rkx = rank(qr[i].l, qr[i].r, qr[i].k+1);
    125             if (rkx>=qr[i].r-qr[i].l+1) printf("%d
    ",INF);
    126             else getRank(qr[i].l, qr[i].r, rkx+1);
    127         }
    128     }
    129     return 0;
    130 }

    2141: 排队

    题目链接

    树套树维护区间逆序对个数;每一次修改只需要处理一下修改前后对答案的正负贡献。

     1 #include<bits/stdc++.h>
     2 const int maxn = 20035;
     3 const int maxNode = 7000035;
     4 
     5 struct node
     6 {
     7     int l,r,val;
     8 }f[maxNode];
     9 int n,m,h[maxn],cnt[maxn];
    10 int tot,rt[maxn],cntl,cntr,svl[maxn],svr[maxn];
    11 long long ans,tmp;
    12 
    13 int read()
    14 {
    15     char ch = getchar();
    16     int num = 0, fl = 1;
    17     for (; !isdigit(ch); ch=getchar())
    18         if (ch=='-') fl = -1;
    19     for (; isdigit(ch); ch=getchar())
    20         num = (num<<1)+(num<<3)+ch-48;
    21     return num*fl;
    22 }
    23 void update(int &rt, int l, int r, int c, int d)
    24 {
    25     if (!rt) rt = ++tot;
    26     f[rt].val += d;
    27     if (l==r) return;
    28     int mid = (l+r)>>1;
    29     if (c <= mid) update(f[rt].l, l, mid, c, d);
    30     else update(f[rt].r, mid+1, r, c, d);
    31 }
    32 void query(int rt, int L, int R, int l, int r)
    33 {
    34     if (!rt) return;
    35     if (L <= l&&r <= R){
    36         tmp += f[rt].val;
    37         return;
    38     }
    39     int mid = (l+r)>>1;
    40     if (L <= mid) query(f[rt].l, L, R, l, mid);
    41     if (R > mid) query(f[rt].r, L, R, mid+1, r);
    42 }
    43 long long fndQuery(int lp, int rp, int L, int R)
    44 {
    45     if (L > R) return 0;
    46     long long ret = 0;
    47     for (int i=lp,u; i; i-=i&-i)
    48         u = rt[i], tmp = 0, query(u, L, R, 1, cnt[0]), ret -= tmp;
    49     for (int i=rp,u; i; i-=i&-i)
    50         u = rt[i], tmp = 0, query(u, L, R, 1, cnt[0]), ret += tmp;
    51     return ret;
    52 }
    53 void backtrack(int l, int r, int L, int R, int f)
    54 {
    55     if (l > r||L > R) return;
    56     ans += fndQuery(l-1, r, L, R)*f;
    57 }
    58 int main()
    59 {
    60     n = read();
    61     for (int i=1; i<=n; i++) h[i] = cnt[i] = read();
    62     std::sort(cnt+1, cnt+n+1);
    63     cnt[0] = std::unique(cnt+1, cnt+n+1)-cnt-1;
    64     for (int i=1; i<=n; i++)
    65     {
    66         h[i] = std::lower_bound(cnt+1, cnt+cnt[0]+1, h[i])-cnt;
    67         for (int p=i; p<=n; p+=p&-p) update(rt[p], 1, cnt[0], h[i], 1);
    68     }
    69     m = read();
    70     for (int i=1; i<=n; i++)
    71         backtrack(1, i-1, h[i]+1, cnt[0], 1);
    72     printf("%lld
    ",ans);
    73     for (int i=1; i<=m; i++)
    74     {
    75         int u = read(), v = read();
    76         if (u > v) std::swap(u, v);
    77         backtrack(1, u-1, h[u]+1, cnt[0], -1);
    78         backtrack(u+1, n, 1, h[u]-1, -1);
    79         backtrack(1, v-1, h[v]+1, cnt[0], -1);
    80         backtrack(v+1, n, 1, h[v]-1, -1);
    81         for (int p=u; p<=n; p+=p&-p) update(rt[p], 1, cnt[0], h[u], -1);
    82         for (int p=v; p<=n; p+=p&-p) update(rt[p], 1, cnt[0], h[v], -1);
    83         if (h[u] > h[v]) ++ans;
    84         if (h[u] < h[v]) --ans;
    85         std::swap(h[u], h[v]);
    86         for (int p=u; p<=n; p+=p&-p) update(rt[p], 1, cnt[0], h[u], 1);
    87         for (int p=v; p<=n; p+=p&-p) update(rt[p], 1, cnt[0], h[v], 1);
    88         backtrack(1, u-1, h[u]+1, cnt[0], 1);
    89         backtrack(u+1, n, 1, h[u]-1, 1);
    90         backtrack(1, v-1, h[v]+1, cnt[0], 1);
    91         backtrack(v+1, n, 1, h[v]-1, 1);
    92         printf("%lld
    ",ans);
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    浅谈双连通分量、强连通分量
    第四届 山东省ACM大学生程序设计竞赛
    第四届 山东省ACM Rescue The Princess(计算几何)
    light oj 1138
    hdoj 2767 Proving Equivalences【求scc&&缩点】【求最少添加多少条边使这个图成为一个scc】
    hdoj 3836 Equivalent Sets【scc&&缩点】【求最少加多少条边使图强连通】
    hdoj 3072 Intelligence System【求scc&&缩点】【求连通所有scc的最小花费】
    hdoj 1827 Summer Holiday【强连通分量&&缩点】
    hdoj 1269 迷宫城堡【scc基础题目】
    light oj 1019【最短路模板】
  • 原文地址:https://www.cnblogs.com/antiquality/p/10453271.html
Copyright © 2020-2023  润新知