zoukankan      html  css  js  c++  java
  • 主席树模板

    区间第 (k)

    (Code)

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int N = 2e5;
    int n , m , rt[N + 5] , ind[N + 5] , a[N + 5] , len , size;
    
    struct segment{
    	int ls , rs , sum;
    }seg[(N << 5) + 5];
    
    inline int read()
    {
    	int res = 0;
    	char ch = getchar();
    	while (ch < '0' || ch > '9') ch = getchar();
    	while (ch >= '0' && ch <= '9') res = (res << 3) + (res << 1) + ch - '0' , ch = getchar();
    	return res;
    }
    
    inline int build(int l , int r)
    {
    	int o = ++size;
    	if (l == r) return o;
    	int mid = (l + r) >> 1;
    	seg[o].ls = build(l , mid) , seg[o].rs = build(mid + 1 , r);
    	return o;
    }
    
    inline int update(int x , int l , int r , int rt)
    {
    	int o = ++size;
    	seg[o].ls = seg[rt].ls , seg[o].rs = seg[rt].rs , seg[o].sum = seg[rt].sum + 1;
    	if (l == r && l == x) return o;
    	int mid = (l + r) >> 1;
    	if (x <= mid) seg[o].ls = update(x , l , mid , seg[rt].ls);
    	else seg[o].rs = update(x , mid + 1 , r , seg[rt].rs);
    	return o;
    }
    
    inline int query(int x , int y , int l , int r , int k)
    {
    	if (l == r) return l;
    	int mid = (l + r) >> 1 , node = seg[seg[y].ls].sum - seg[seg[x].ls].sum;
    	if (node >= k) return query(seg[x].ls , seg[y].ls , l , mid , k);
    	else return query(seg[x].rs , seg[y].rs , mid + 1 , r , k - node);
    }
    
    int main()
    {
    	n = read() , m = read();
    	for(register int i = 1; i <= n; i++) a[i] = read() , ind[i] = a[i];
    	sort(ind + 1 , ind + n + 1);
    	len = unique(ind + 1 , ind + n + 1) - ind - 1;
    	rt[0] = build(1 , len);
    	for(register int i = 1; i <= n; i++)
    	{
    		int x = lower_bound(ind + 1 , ind + len + 1 , a[i]) - ind;
    		rt[i] = update(x , 1 , len , rt[i - 1]);
    	}
    	int x , y , z;
    	for(register int i = 1; i <= m; i++)
    	{
    		x = read() , y = read() , z = read();
    		printf("%d
    " , ind[query(rt[x - 1] , rt[y] , 1 , len , z)]);
    	}
    }
    

    (update) 写法

    int size, rt[N];
    struct segment{int ls, rs, s;}seg[N * 16];
    
    void update(int &p, int pre, int l, int r, int v)
    {
    	p = ++size;
    	seg[p] = seg[pre], seg[p].s = seg[pre].s + 1;
    	if (l == r) return;
    	int mid = (l + r) >> 1;
    	if (v <= mid) update(seg[p].ls , seg[pre].ls, l, mid, v);
    	else update(seg[p].rs, seg[pre].rs, mid + 1, r, v);
    }
    
    int query(int p, int pre, int l, int r, int v)
    {
    	int o = seg[p].s - seg[pre].s;
    	if (!o) return 0;
    	if (l == r) return o;
    	int mid = (l + r) >> 1;
    	if (v <= mid) return query(seg[p].ls, seg[pre].ls, l, mid, v); 
    	return query(seg[p].rs, seg[pre].rs, mid + 1, r, v);
    }
    
  • 相关阅读:
    mysqldump备份数据
    windows上mysql5.7服务启动报错
    Java NIO:FileChannel数据传输
    HBase过滤器:SingleColumnValueFilter和FirstKeyOnlyFilter一起使用的问题
    Java自定义注解
    Kafka Connect使用入门-Mysql数据导入到ElasticSearch
    Kafka中使用Avro编码、解码消息
    堆和栈
    Java中基本数据类型byte,short,char,int,long,float,double 取值范围
    对快速排序的一点小探究
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/13442923.html
Copyright © 2011-2022 走看看