可持久化线段树(主席树)学习笔记(1)

来源:互联网 发布:gps数据采集仪器 编辑:程序博客网 时间:2024/06/05 06:16

集训学了些妙妙的数据结构和晕晕的知识(线性基)。

qaq代码里注释解释的很清楚了。。再详细的见:
会施放魔法的小女巫打开的传送门

静态区间第K大离散化不去重主席树模板

#include<bits/stdc++.h>using namespace std;const int MAXN=2e5+5;int n,m;struct node{    int l,r,sum;}T[MAXN*60];struct A{    int x,idx;    bool operator<(const A&rhs)const{        return x<rhs.x;    }}a[MAXN];int rk[MAXN],rt[MAXN],cnt;void insert(int num,int &p,int l,int r){     T[cnt++]=T[p];p=cnt-1;    T[p].sum++;    if(l==r)return;    int mid=(l+r)>>1;    if(num<=mid)insert(num,T[p].l,l,mid);//在l-r(离散化后的数据范围里查找)     else insert(num,T[p].r,mid+1,r);}int query(int i,int j,int k,int l,int r){    if(l==r)return l;    int mid=(l+r)>>1,tem=T[T[j].l].sum-T[T[i].l].sum;    if(k<=tem)return query(T[i].l,T[j].l,k,l,mid);    else return query(T[i].r,T[j].r,k-tem,mid+1,r);}int main(){    T[0].l=T[0].r=T[0].sum=0;//空节点     rt[0]=0;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        scanf("%d",&a[i].x);        a[i].idx=i;//记录原数列序列号     }    sort(a+1,a+n+1);    for(int i=1;i<=n;i++)rk[a[i].idx]=i;//把序列号映射到rk数组  rk的值(序列位置离散化以后的值)     cnt=1;    for(int i=1;i<=n;i++){        rt[i]=rt[i-1];        insert(rk[i],rt[i],1,n);//为原序列 建线段树,值域1-n是因为没有去重,一共离散化了n个数。     }    while(m--){        int i,j,k;        scanf("%d",&i);        printf("%d %d\n",T[rt[i]].sum,T[rt[i]].l);    }    return 0;}
原创粉丝点击