• K大树


    权值线段树套线段树

    之前没有做过权值线段树套外层树,也是第一次写动态开点的完整线段树

    push_down 的时候要动态开点。其实跟普通线段树是一样的。

    写之前一定要先想清楚。外层的线段树是将值离散化后建的,外层的线段树可以用 o<<1o<<1|1 , 这样进行转移。内层的线段树需要动态开点,所以需要数组 lc[N] , rc[N]

    要计算开的空间大小。

    /*
     * @Author: zhl
     * @Date: 2020-11-17 13:55:59
     */
    #include<bits/stdc++.h>
    #define mid (l + r >> 1)
    #define lo (o << 1)
    #define ro (o << 1 | 1)
    using ll = long long;
    using namespace std;
    
    const int N = 5e4 + 10, P = N * 17 * 17, M = 4 * N;
    int n, m;
    
    int root[M], lc[P], rc[P], lz[P], tot;
    ll sum[P];
    
    void push_down(int u,int l,int r) {
    	if (!lc[u])lc[u] = ++tot;
    	lz[lc[u]] += lz[u];
    	if (!rc[u])rc[u] = ++tot;
    	lz[rc[u]] += lz[u];
    
    	sum[lc[u]] += (mid - l + 1) * lz[u];
    	sum[rc[u]] += (r - mid) * lz[u];
    
    	lz[u] = 0;
    }
    void updt(int& rt, int L,int R, int o = 1, int l = 1, int r = n) {
    	if (!rt) rt = ++tot;
    	if (L <= l and r <= R) {
    		lz[rt] ++;
    		//sum[rt] += R - L + 1;//我是傻逼草
    		sum[rt] += r - l + 1;
    		return;
    	}
    	if (lz[rt])push_down(rt, l , r);
    	if (L <= mid)updt(lc[rt], L, R, lo, l, mid);
    	if (R > mid)updt(rc[rt], L, R, ro, mid + 1, r);
    	sum[rt] = sum[lc[rt]] + sum[rc[rt]];
    }
    
    ll query(int rt, int L, int R, int o = 1, int l = 1, int r = n) {
    	if (!rt)return 0;
    	if (L <= l and r <= R) {
    		return sum[rt];
    	}
    	if (lz[rt])push_down(rt, l, r);
    	ll ans = 0;
    	if (L <= mid)ans += query(lc[rt], L, R, lo, l, mid);
    	if (R > mid) ans += query(rc[rt], L, R, ro, mid + 1, r);
    	return ans;
    }
    
    
    int cntID, id[N];
    
    void add(int L,int R, int pos, int o = 1, int l = 1, int r = cntID) {
    	updt(root[o], L, R);
    	if (l == r)return;
    	if (pos <= mid)add(L, R, pos, lo, l, mid);
    	else add(L, R, pos, ro, mid + 1, r);
    }
    
    int get_kth(int L,int R,ll k,int o = 1, int l = 1, int r = cntID) {
    	if (l == r)return id[l];
    	
    	ll num = query(root[ro], L, R);
    	if (num >= k) return get_kth(L, R, k, ro, mid + 1, r);
    	else return get_kth(L, R, k - num, lo, l, mid);
    }
    
    
    struct {
    	int op, a, b, c;
    }q[N];
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= m; i++) {
    		scanf("%d%d%d%d", &q[i].op, &q[i].a, &q[i].b, &q[i].c);
    		if (q[i].op == 1) {
    			id[++cntID] = q[i].c;
    		}
    	}
    	sort(id + 1, id + 1 + cntID);
    	cntID = unique(id + 1, id + 1 + cntID) - id - 1;
    
    	for (int i = 1; i <= m; i++) {
    		if (q[i].op == 1)q[i].c = lower_bound(id + 1, id + 1 + cntID, q[i].c) - id;
    	}
    
    	for (int i = 1; i <= m; i++) {
    		if (q[i].op == 1) {
    			add(q[i].a, q[i].b, q[i].c);
    		}
    		else {
    			printf("%d
    ", get_kth(q[i].a, q[i].b, q[i].c));
    		}
    	}
    }
    
  • 相关阅读:
    C winpcap 网络抓包 并获取IP TCP 协议的相关信息
    python基础
    k8s部署测试实例
    node节点的部署
    k8s集群之master节点部署
    k8s集群之Docker安装镜像加速器配置与k8s容器网络
    k8s集群部署之环境介绍与etcd数据库集群部署
    docker存储管理
    docker 镜像仓库的安装与使用
    docker 镜像管理
  • 原文地址:https://www.cnblogs.com/sduwh/p/13994034.html
Copyright © 2020-2023  润新知