玲珑杯 1157 造物主的戒律
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玲珑杯 1157 造物主的戒律相关的知识,希望对你有一定的参考价值。
传送门:http://www.ifrog.cc/acm/problem/1157
题意:
给一个数组,n多次询问,每次询问区间[l,r]中小于等于x的第k1小的数,大于x的第k2小的数。
题解:
比较裸的主席树了,多了个限制,对于每个询问的前一部分直接求区间第k1小的数和x比较一下就行了,对于后一部分查询先判断x为第几小的数然后加上k2就行了。。。
题解说是可持续化字典树(不还是主席树吗)。。。还没想太明白。。。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=400000+100; 4 int a[maxn],tot=0,r,l,x,k1,k2,n,m; 5 int root[maxn]; 6 struct node { 7 int l, r , sum; 8 }t[maxn*40]; 9 vector<int> g; 10 int getid(int x) { 11 return lower_bound(g.begin(),g.end(),x)-g.begin()+1; 12 } 13 14 void update(int l, int r, int &x, int y,int pos) { 15 t[++tot]=t[y]; t[tot].sum++; x=tot; 16 if(l==r) return; 17 int mid=l+r>>1; 18 if(mid>=pos)update(l,mid,t[x].l,t[y].l,pos); 19 else update(mid+1,r,t[x].r,t[y].r,pos); 20 } 21 22 int newupdate(int l, int r, int pos, int x, int y) { 23 if(t[x].sum-t[y].sum==0) return 0; 24 if(l==r) return t[x].sum-t[y].sum; 25 int ans=0; 26 int mid=l+r>>1; 27 if(mid>=pos) ans+=newupdate(l,mid,pos,t[x].l,t[y].l); 28 else { 29 ans+=t[t[x].l].sum-t[t[y].l].sum; 30 ans+=newupdate(mid+1,r,pos,t[x].r,t[y].r); 31 } 32 return ans; 33 } 34 int query(int l, int r, int x, int y, int k) { 35 if(l==r) return l; 36 int mid=l+r>>1; 37 int sum=t[t[y].l].sum-t[t[x].l].sum; 38 if(sum>=k)return query(l,mid,t[x].l,t[y].l,k); 39 else return query(mid+1,r,t[x].r,t[y].r,k-sum); 40 } 41 int main() { 42 #ifdef ac 43 freopen("in.txt","r",stdin); 44 #endif 45 scanf("%d%d",&n,&m); 46 for(int i=1;i<=n;++i){ 47 scanf("%d",&a[i]); 48 g.push_back(a[i]); 49 } 50 sort(g.begin(),g.end()); 51 g.erase(unique(g.begin(),g.end()),g.end()); 52 for(int i=1;i<=n;++i) update(1,n,root[i],root[i-1],getid(a[i])); 53 for(int i=1;i<=m;++i) { 54 scanf("%d%d%d%d%d",&l,&r,&x,&k1,&k2); 55 int tans1=-1,tans2=-1,tmp; 56 if(r-l+1>=k1) tans1=query(1,n,root[l-1],root[r],k1)-1; 57 if(tans1==-1||g[tans1]>x) tans1=-1; else tans1=g[tans1]; 58 tmp=newupdate(1,n,upper_bound(g.begin(),g.end(),x)-g.begin(),root[r],root[l-1]); 59 if(r-l+1>=tmp+k2)tans2=query(1,n,root[l-1],root[r],k2+tmp)-1; 60 if(tans2!=-1) tans2=g[tans2]; 61 printf("%d %d\n",tans1,tans2); 62 } 63 return 0; 64 }
以上是关于玲珑杯 1157 造物主的戒律的主要内容,如果未能解决你的问题,请参考以下文章