#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <sstream> #include <map> #include <set> #include <queue> #include <stdlib.h> typedef long long ll; #define maxn 200010 using namespace std; int c[maxn]; int lowbit(int x) { return x&(-x); } void add(int x) //更新数据,标准的updata在下面,在(x,y,z)处的值加1,所以k的值均为1 { for(int i=x; i<maxn ; i+=lowbit(i)) { c[i]+=1; } } //void updata(int i,int k) //k的值为1 //{ // while(i<=maxn) // { // c[i]+=k; // i+=lowbit(i); // } //} int getsum(int x) { int ans=0; while(x>0) { ans+=c[x]; x-=lowbit(x); } // for(int i=x;i>0;i-=lowbit(i)) // ans += c[i]; return ans; } int main() { int k; int cnt=0; //用cnt记录op=1一共进行了几次,如果最后op=1的次数小于要求的能量值总和(k),则直接输出-1 double x,y,z; int n; cin >> n; while(n--) { int op; cin >> op; if(op==1) { cin >> x >> y >> z; cnt++; double a = sqrt(x*x+y*y+z*z); int aa = ceil(a); //向上取整 add(aa); //在距离原点距离为aa处,加一点能量值 } else if(op==2) { cin >> k; if(k>cnt) { printf("-1\n"); continue; } //二分查找 -》 树状数组一定是从小到大进行排序的。 int l=0,r=maxn,mid; while(l<=r) //求的能量值,是从0~mid的能量值 { mid = (l+r)/2; if(getsum(mid)>=k) r=mid-1; else l=mid+1; } printf("%d\n",l); } } return 0; }