zoukankan      html  css  js  c++  java
  • poj2104 主席树裸题

     空间大小:n*lgn

     复杂度:建树n*lgn  查询lgn

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=1e5+5;
    struct Node
    {
         int L,R,num;
    }tree[20*maxn];
    struct Rank
    {
         int x,id;
         bool operator <(Rank a)const
         {
             return x<a.x;
         }
    }ran[maxn];
    int root[maxn],num[maxn];
    int cnt=1;
    void updata(int x,int &rt,int a,int b)//建树操作
    {
        tree[cnt++]=tree[rt];//新建子树并且复制
        rt=cnt-1;
        tree[rt].num++;
        if(a==b)return;
        int mid=(a+b)/2;
        if(x<=mid)
            updata(x,tree[rt].L,a,mid);
        else
            updata(x,tree[rt].R,mid+1,b);
    }
    int quer(int a,int b,int k,int s,int o)//查询操作,查询a—b区间,第k位置,属性为s—o的节点
    {
        int d=tree[tree[b].L].num-tree[tree[a].L].num;
        if(s==o)return s;
        if(k<=d)
            return quer(tree[a].L,tree[b].L,k,s,(s+o)/2);
        else
            return quer(tree[a].R,tree[b].R,k-d,(s+o)/2+1,o);
    }
    int main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&ran[i].x);
            ran[i].id=i;//ran和num的作用是离散处理
        }
        sort(ran+1,ran+n+1);
        for(int i=1;i<=n;i++)
        {
            num[ran[i].id]=i;
        }
        for(int i=1;i<=n;i++)
        {
            root[i]=root[i-1];//复制上一个树
            updata(num[i],root[i],1,n);
        }
        for(int i=1;i<=m;i++)
        {
            int l,r,k;
            scanf("%d %d %d",&l,&r,&k);
            printf("%d
    ",ran[quer(root[l-1],root[r],k,1,n)].x);
        }
        return 0;
    }
    

      

  • 相关阅读:
    OpenCMS创建导航条
    C++笔记(2)面向对象编程
    C++笔记(3)模板与泛型编程
    多线程和信号量
    C++笔记(4)用于大型程序的工具
    C++笔记(5)特殊工具与技术
    C++笔记(1)类
    Effective C++ 笔记(1)
    C语言笔记整理(2)
    C语言笔记整理(3)
  • 原文地址:https://www.cnblogs.com/carcar/p/9046621.html
Copyright © 2011-2022 走看看