对数据结构的不熟练
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 }