1. 程式人生 > >洛谷3348

洛谷3348

ons ID pre algo ace src 模板 bool urn

可持久化線段樹模板

1.結構體的打法

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn=200010;
struct data{int l,r,sz;}tr[maxn<<5];
int n,m,cnt,key,a[maxn],rk[maxn],id[maxn],rt[maxn];

inline int read(int &x){
    char ch=getchar();x=0;
    while(!isdigit(ch))ch=getchar();
    
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-0;ch=getchar();} } bool cmp(const int &x,const int &y){ return a[x]<a[y]; } void build(int l,int r,int &pos){ tr[++cnt]=tr[pos];pos=cnt;tr[cnt].sz++; if(l==r)return; int mid=(l+r)>>1; if(key<=mid)build(l,mid,tr[cnt].l);else
build(mid+1,r,tr[cnt].r); } int query(int l,int r,int x,int y,int k){ if(l==r)return l; int mid=(l+r)>>1,sz=tr[tr[y].l].sz-tr[tr[x].l].sz; if(k<=sz)return query(l,mid,tr[x].l,tr[y].l,k); else return query(mid+1,r,tr[x].r,tr[y].r,k-sz); } int main(){ read(n);read(m);
for(int i=1;i<=n;i++){read(a[i]);id[i]=i;} sort(id+1,id+n+1,cmp); for(int i=1;i<=n;i++)rk[id[i]]=i; for(int i=1;i<=n;i++){ rt[i]=rt[i-1]; key=rk[i];build(1,n,rt[i]); } while(m--){ int l,r,k;read(l);read(r);read(k); printf("%d\n",a[id[query(1,n,rt[l-1],rt[r],k)]]); } }

技術分享圖片

2.數組打法

#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 200005
using namespace std;
int n,m,cnt,rt[maxn],rk[maxn];
int l[maxn<<5],r[maxn<<5],siz[maxn<<5],a[maxn],id[maxn];

inline void read(int &x){
    char ch=getchar();x=0;
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-0;ch=getchar();}
}

inline void buildtr(int &root,int L,int R,int now){
    l[++cnt]=l[root];r[cnt]=r[root];siz[cnt]=siz[root]+1;
    root=cnt;
    if(L==R)return;
    int mid=(L+R)>>1;
    if(now<=mid)buildtr(l[cnt],L,mid,now);else buildtr(r[cnt],mid+1,R,now);
}

inline int query(int L,int R,int x,int y,int k){
    if(L==R)return L;
    int mid=(L+R)>>1,sz=siz[l[y]]-siz[l[x]];
    if(sz>=k)return query(L,mid,l[x],l[y],k);else return query(mid+1,R,r[x],r[y],k-sz);
}

inline bool cmp(int x,int y){
    return a[x]<a[y];
}

int main(){
    read(n);read(m);
    for(int i=1;i<=n;i++){read(a[i]);id[i]=i;}
    sort(id+1,id+n+1,cmp);
    for(int i=1;i<=n;i++)rk[id[i]]=i;
    for(int i=1;i<=n;i++){
        rt[i]=rt[i-1];buildtr(rt[i],1,n,rk[i]);
    }
    while(m--){
        int L,R,k;read(L);read(R);read(k);printf("%d\n",a[id[query(1,n,rt[L-1],rt[R],k)]]);
    }
}

技術分享圖片

洛谷3348