可持久化线段树(主席树)

来源:互联网 发布:苏菲娜护肤品知乎 编辑:程序博客网 时间:2024/05/17 08:32
/*    可持久优化线段树    POJ2104 区间第k大值 k-th number    by sbn    2017-12-21 */#include<iostream>#include<cstdio>#include<vector>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;struct node{    int l,r;    int num;    //存放第i个值在原序列排第几     int sum;    //线段树结点里保存的值 }   tree[5000001];int n,m,tot=0,head[5000001];//每个结点在线段树中标号 int san[5000001]; //存放原有值的排序 void build(int l,int r,int &u){    u=++tot;    tree[u].sum=0;    if (l==r)   return;    build(l,(l+r)>>1,tree[u].l);    build((l+r)/2+1,r,tree[u].r);}//一棵空树 void update(int last,int u,int l,int r,int &x){ //     x=++tot;    tree[x].l=tree[last].l;    tree[x].r=tree[last].r;    tree[x].sum=tree[last].sum+1;    if (l==r)   return;    int mid=(l+r)/2;    if(u<=mid)  update(tree[last].l,u,l,mid,tree[x].l);    else update(tree[last].r,u,mid+1,r,tree[x].r);}int query(int s,int t,int l,int r,int k){    if (l==r)   return l;    int mid=(l+r)/2;    int cnt=tree[tree[t].l].sum-tree[tree[s].l].sum;    if (k<=cnt)        return query(tree[s].l,tree[t].l,l,mid,k);        return query(tree[s].r,tree[t].r,mid+1,r,k-cnt);}inline void debug(){        cout<<"san:"<<endl;    for (int i=1;i<=n;i++)  cout<<san[i]<<" ";cout<<endl;    cout<<"num:"<<endl;    for (int i=1;i<=n;i++)  cout<<tree[i].num<<" ";cout<<endl;    cout<<"sum:"<<endl;    for (int i=1;i<=n;i++)  cout<<tree[i].sum<<" ";cout<<endl;    cout<<"head:"<<endl;    for (int i=0;i<=n;i++)  cout<<head[i]<<" ";cout<<endl;    cout<<"l,r"<<endl;    for (int i=0;i<=n;i++)  cout<<tree[head[i]].l<<","<<tree[head[i]].r<<" ";cout<<endl;}int main(){    int x,y,z;    cin>>n>>m;    for (int i=1;i<=n;i++)    {        cin>>san[i];        tree[i].num=san[i];    }    sort(san+1,san+n+1);    int cnt=unique(san+1,san+n+1)-san-1;    //去重     cout<<cnt<<endl;    build(1,cnt,head[0]);    debug();    update(head[0],tree[1].num,1,cnt,head[1]);    debug();    for (int i=1;i<=n;i++)        tree[i].num=lower_bound(san+1,san+n+1,tree[i].num)-san;    for (int i=1;i<=n;i++)        update(head[i-1],tree[i].num,1,cnt,head[i]);    //debug();    for (int i=1;i<=m;i++){        cin>>x>>y>>z;        cout<<san[query(head[x-1],head[y],1,cnt,z)]<<endl;    }    return 0;} 
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 黄河公棚 黄河大桥 黄河全长 什么的黄河 黄河简介 黄河的资料 黄河黄河 黄河一日游 黄河峡谷 黄河旅游 黄河壶口 黄河实业 黄河玉 黄河枪 黄河人家 黄河在哪 黄河多长 黄河流经 黄河九曲 黄河以南 黄河以北 黄河大坝 黄河隧道 黄河宫 黄河小学 黄河大堤 黄河水 黄河阵 黄河湿地 黄河改道 黄河站 黄河电视机 黄河尸王 黄河蜜瓜 黄河渡 黄河长江 黄河中学 渡黄河 黄河大学 黄河鲤 黄河鱼