您的位置:首页 > 其它

P3834 【模板】可持久化线段树 1(主席树)

2018-07-28 21:32 549 查看
传送门

板子,大佬的题解写的真好

ps:看了看attack大佬的板子……跑的飞快……

然后抄了抄……慢的要命(评测机玄学问题?)

真不知道大佬常数怎么写的……

更神仙的是大佬居然都不先建树直接加点→_→

怎么过的orz

// luogu-judger-enable-o2
//minamoto
#include<bits/stdc++.h>
#define N 200005
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<15,stdin),p1==p2)?EOF:*p1++)
char buf[1<<15],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=0;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*10+num);
(flag)&&(res=-res);
#undef num
return res;
}
int sum[N<<5],L[N<<5],R[N<<5];
int a
,b
,t
;
int n,q,m,cnt=0;
int build(int l,int r){
int rt=++cnt;
sum[rt]=0;
if(l<r){
int mid=(l+r)>>1;
L[rt]=build(l,mid);
R[rt]=build(mid+1,r);
}
return rt;
}
int update(int last,int l,int r,int x){
int rt=++cnt;
L[rt]=L[last],R[rt]=R[last],sum[rt]=sum[last]+1;
if(l<r){
int mid=(l+r)>>1;
if(x<=mid) L[rt]=update(L[last],l,mid,x);
else R[rt]=update(R[last],mid+1,r,x);
}
return rt;
}
int query(int u,int v,int l,int r,int k){
if(l>=r) return l;
int x=sum[L[v]]-sum[L[u]];
int mid=(l+r)>>1;
if(x>=k) return query(L[u],L[v],l,mid,k);
else return query(R[u],R[v],mid+1,r,k-x);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),q=read();
for(int i=1;i<=n;++i)
b[i]=a[i]=read();
sort(b+1,b+1+n);
m=unique(b+1,b+1+n)-b-1;
t[0]=build(1,m);
for(int i=1;i<=n;++i){
int k=lower_bound(b+1,b+1+m,a[i])-b;
t[i]=update(t[i-1],1,m,k);
}
while(q--){
int x,y,z;
x=read(),y=read(),z=read();
int k=query(t[x-1],t[y],1,m,z);
printf("%d\n",b[k]);
}
return 0;
}


然后是照着attack大佬的板子写的

算了以后用这个板子

// luogu-judger-enable-o2
// luogu-judger-enable-o2
//minamoto
#include<bits/stdc++.h>
#define N 200005
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=0;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*10+num);
(flag)&&(res=-res);
#undef num
return res;
}
char obuf[1<<24],*o=obuf;
void print(int x){
if(x>9) print(x/10);
*o++=x%10+48;
}
int sum[N<<5],L[N<<5],R[N<<5];
int a
,b
,t
;
int n,q,m,cnt=0;
void update(int last,int &now,int l,int r,int x){
if(!now) now=++cnt;
sum[now]=sum[last]+1;
if(l==r) return;
int mid=(l+r)>>1;
if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
else L[now]=L[last],update(R[last],R[now],mid+1,r,x);
}
int query(int u,int v,int l,int r,int k){
if(l>=r) return l;
int x=sum[L[v]]-sum[L[u]];
int mid=(l+r)>>1;
if(x>=k) return query(L[u],L[v],l,mid,k);
else return query(R[u],R[v],mid+1,r,k-x);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),q=read();
for(int i=1;i<=n;++i)
b[i]=a[i]=read();
sort(b+1,b+1+n);
m=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;++i){
int k=lower_bound(b+1,b+1+m,a[i])-b;
update(t[i-1],t[i],1,m,k);
}
while(q--){
int x,y,z;
x=read(),y=read(),z=read();
int k=query(t[x-1],t[y],1,m,z);
print(b[k]);
*o++='\n';
}
fwrite(obuf,o-obuf,1,stdout);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: