题解
通过观察发现,
每执行一次 1 w
,原先的数据下标变为原来的2倍,整个区间的数据个数变为原来的两倍
即第i次操作,整个区间的个数增加
2
i
2^i
2i个
已知区间最大
1
0
18
10^{18}
1018,最多含有59个不同的数,
59 - 1,152,921,504,606,846,974
60 - 2,305,843,009,213,693,950
每执行一次 2 l r k
,对于新增加进来的w而言,[1,r] 内含有
r
2
\cfrac{r}{2}
2r 个,[1,l-1] 内含有
l
−
1
2
\cfrac{l-1}{2}
2l−1 个,
同理倒推上上次新增的w’,[1,r] 内含有
1
2
∗
r
2
\cfrac{1}{2}*\cfrac{r}{2}
21∗2r 个,[1,l-1] 内含有
1
2
∗
l
−
1
2
个
\cfrac{1}{2}*\cfrac{l-1}{2}个
21∗2l−1个
因为最多将近60个不同的数字,操作次数n只有 1 0 5 10^5 105,所以,直接sort查第k大
注意一下区间端点的奇偶性引起的数值的变化
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
struct node {
ll x,num;
}b[N];
bool cmp(node a,node b){
return a.x<b.x;
}
ll a[N];
int tot=0;
ll l,r,k,w;
int main(){
ios::sync_with_stdio(0);
int T;
cin>>T;
for (int cs = 1,op; cs <= T; ++cs) {
cin>>op;
if(op==1){
cin>>w;
a[++tot]=w;
}else{
cin>>l>>r>>k;
int cnt=0;
for (int i = tot; i ; --i) {
b[++cnt]={a[i],(r+1)/2-l/2};// [1,r] (1+r)/2
/*
b[++cnt].x=a[i];
b[cnt].num=(r+1)/2-l/2;
*/
r=r/2;
l=(l+1)/2;
if(l>r)break;//注意这里 r会变成0 但是l最小1 超出范围就没必要了
}
sort(b+1,b+1+cnt,cmp);
for (int i = 1; i <= cnt; ++i) {
k-=b[i].num;
if(k<=0){
cout<<b[i].x<<endl;
break;
}
}
}
}
return 0;
}