• HYSBZ 1901 Dynamic Rankings 树状数组套主席树


    ZOJ上面这题内存限制太严格,裸的树套树主席树搞法过不去,BZOJ上面这个放的比较松,可以过。

    其实就是利用树状数组维护n颗主席树,然后利用前缀和性质求解第k大。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <deque>
    #include <bitset>
    #include <list>
    #include <cstdlib>
    #include <climits>
    #include <cmath>
    #include <ctime>
    #include <algorithm>
    #include <stack>
    #include <sstream>
    #include <numeric>
    #include <fstream>
    #include <functional>
     
    using namespace std;
     
    #define MP make_pair
    #define PB push_back
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const int INF = INT_MAX / 3;
    const double eps = 1e-8;
    const LL LINF = 1e17;
    const double DINF = 1e60;
    const int maxn = 5e4 + 10;
    const int maxm = maxn * 67;
    const int maxq = 1e4 + 10;
    
    struct Query {
    	char cmd;
    	int l, r, k;
    	Query(char cmd = 0, int l = 0, int r = 0, int k = 0): 
    		cmd(cmd), l(l), r(r), k(k) {}
    };
    
    int sumv[maxm], lc[maxm], rc[maxm], cnt, C[maxn];
    int n, m, num[maxn + maxq], numcnt, a[maxn];
    Query ask[maxq];
    
    int lowbit(int x) {
    	return x & (-x);
    }
    
    void init() {
    	cnt = numcnt = 0;
    	memset(C, 0, sizeof(C));
    }
    
    void build(int rt, int l, int r) {
    	sumv[rt] = 0;
    	if(l == r) return;
    	int mid = (l + r) >> 1;
    	lc[rt] = cnt++; rc[rt] = cnt++;
    	build(lc[rt], l, mid);
    	build(rc[rt], mid + 1, r);
    }
    
    int update(int prt, int pos, int Val) {
    	int nrt = cnt++, ret = nrt;
    	sumv[nrt] = sumv[prt] + Val;
    	int l = 0, r = numcnt - 1;
    	while(l < r) {
    		int mid = (l + r) >> 1;
    		if(pos <= mid) {
    			lc[nrt] = cnt++; rc[nrt] = rc[prt];
    			sumv[lc[nrt]] = sumv[lc[prt]] + Val;
    			nrt = lc[nrt]; prt = lc[prt];
    			r = mid;
    		}
    		else {
    			rc[nrt] = cnt++; lc[nrt] = lc[prt];
    			sumv[rc[nrt]] = sumv[rc[prt]] + Val;
    			nrt = rc[nrt]; prt = rc[prt];
    			l = mid + 1;
    		}
    	}
    	return ret;
    }
    
    void gao(int tid, int pos, int Val) {
    	while(tid <= n) {
    		int ret = update(C[tid], pos, Val);
    		C[tid] = ret;
    		tid += lowbit(tid);
    	}
    }
    
    int lrt[maxn], rrt[maxn];
    int query(int ql, int qr, int k) {
    	int lcnt = 0, rcnt = 0;
    	ql--;
    	while(ql > 0) {
    		lrt[lcnt++] = C[ql];
    		ql -= lowbit(ql);
    	}
    	while(qr > 0) {
    		rrt[rcnt++] = C[qr];
    		qr -= lowbit(qr);
    	}
    	int l = 0, r = numcnt - 1;
    	while(l < r) {
    		int mid = (l + r) >> 1, lsum = 0, rsum = 0;
    		for(int i = 0; i < lcnt; i++) lsum += sumv[lc[lrt[i]]];
    		for(int i = 0; i < rcnt; i++) rsum += sumv[lc[rrt[i]]];
    		if(rsum - lsum >= k) {
    			r = mid;
    			for(int i = 0; i < lcnt; i++) lrt[i] = lc[lrt[i]];
    			for(int i = 0; i < rcnt; i++) rrt[i] = lc[rrt[i]];
    		}
    		else {
    			l = mid + 1; k -= (rsum - lsum);
    			for(int i = 0; i < lcnt; i++) lrt[i] = rc[lrt[i]];
    			for(int i = 0; i < rcnt; i++) rrt[i] = rc[rrt[i]];
    		}
    	}
    	return l;
    }
    
    int getid(int Val) {
    	return lower_bound(num, num + numcnt, Val) - num;
    }
    
    int main() {
    	init();
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i++) {
    		scanf("%d", &a[i]);
    		num[numcnt++] = a[i];
    	}
    	char cmd[5];
    	int l, r, k;
    	for(int i = 1; i <= m; i++) {
    		scanf("%s", cmd);
    		if(cmd[0] == 'Q') {
    			scanf("%d%d%d", &l, &r, &k);
    			ask[i] = Query(cmd[0], l, r, k);
    		}
    		else {
    			scanf("%d%d", &l, &k);
    			ask[i] = Query(cmd[0], l, 0, k);
    			num[numcnt++] = k;
    		}
    	}
    	sort(num, num + numcnt);
    	numcnt = unique(num, num + numcnt) - num;
    	build(0, 0, numcnt - 1);
    	for(int i = 1; i <= n; i++) {
    		gao(i, getid(a[i]), 1);
    	}
    	for(int i = 1; i <= m; i++) {
    		if(ask[i].cmd == 'Q') printf("%d
    ", num[query(ask[i].l, ask[i].r, ask[i].k)]);
    		else {
    			int prev = getid(a[ask[i].l]), now = getid(ask[i].k);
    			a[ask[i].l] = ask[i].k;
    			gao(ask[i].l , prev, -1); gao(ask[i].l, now, 1);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:

    es -Aggregations
    散列表学习
    SpringCloud (一)——基本的搭建
    1.5 中不支持 lambda 表达 java
    区块链 (一)——基础
    线性表
    Redis(四)——消息队列
    rune is alias of int32
    wall time
  • 原文地址:https://www.cnblogs.com/rolight/p/4084741.html
Copyright © 2020-2023  润新知