改了一上午改到怀疑人生,结果是因为这个,好像是直接用快读那样进去容易炸,多打一点也费不了多少时间,平平淡淡才是真
printf("%d\n",b[query(1,size,rt[rd()-1],rt[rd()],rd())]);
好像数组大小有窍门,然而我并没有管就开了那么大,好像什么什么乘40
emmm洛谷测试出来是这样的
然后是poj
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=200000+10; 4 #define lson l,mid 5 #define rson mid+1,r 6 int n,m,a[N],b[N],cnt=0;//a原 b离散后 7 int rt[N],ll[N<<5],rr[N<<5],sum[N<<5]; 8 //根节点 左子树下标 右子树下标 个数 9 inline int rd() 10 { 11 int x=0,w=0;char ch=0; 12 while(!isdigit(ch)) w|=ch=='-',ch=getchar(); 13 while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 14 return w?-x:x; 15 } 16 17 int build(int l,int r)// 18 { 19 int rtt=++cnt; 20 if(l<r) 21 { 22 int mid=(l+r)>>1; 23 ll[rtt]=build(lson); 24 rr[rtt]=build(rson); 25 } 26 return rtt; 27 } 28 29 int update(int l,int r,int pre,int x) 30 {//左右 前一个 修改点 31 int rtt=++cnt; 32 ll[rtt]=ll[pre],rr[rtt]=rr[pre],sum[rtt]=sum[pre]+1; 33 if(l==r) return rtt; 34 int mid=(l+r)>>1; 35 if(x<=mid) ll[rtt]=update(lson,ll[rtt],x);//在左区间 36 else rr[rtt]=update(rson,rr[rtt],x);//在右区间 37 return rtt; 38 } 39 40 int query(int l,int r,int u,int v,int k) 41 {//查询区间 区间 第k大 42 if(l==r) return l; 43 int mid=(l+r)>>1,x=sum[ll[v]]-sum[ll[u]]; 44 if(x>=k) return query(lson,ll[u],ll[v],k);//左区间 45 else return query(rson,rr[u],rr[v],k-x);//右区间 46 } 47 48 int main() 49 { 50 n=rd(),m=rd(); 51 for(int i=1;i<=n;i++) 52 a[i]=rd(),b[i]=a[i]; 53 sort(b+1,b+1+n); 54 int size=unique(b+1,b+1+n)-b-1; 55 rt[0]=build(1,size); 56 for(int i=1;i<=n;i++) 57 { 58 a[i]=lower_bound(b+1,b+size+1,a[i])-b;// 59 rt[i]=update(1,size,rt[i-1],a[i]); 60 } 61 while(m--) 62 { 63 int x=rd(),y=rd(),k=rd(); 64 printf("%d\n",b[query(1,size,rt[x-1],rt[y],k)]); 65 } 66 // printf("%d\n",b[query(1,size,rt[rd()-1],rt[rd()],rd())]); //万恶之源 67 return 0; 68 }