玲珑杯 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 }
View Code

 

posted on 2017-08-27 16:40  仰望咸鱼Orzzzz  阅读(138)  评论(0编辑  收藏  举报

导航