NC53370. Forsaken的三维数点
描述
输入描述
第一行一个表示操作的次数。接下来每行首先一个整数表示操作的种类。如果,接下来个整数表示能量值增加的坐标。如果,接下来一个整数表示要求的能量值总和。
输出描述
对于每个的操作,输出一个整数表示球的半径。(数据保证至少有一个操作)如果没有满足答案的半径,输出。
示例1
输入:
2 1 1 1 1 2 1
输出:
2
C++14(g++5.4) 解法, 执行用时: 635ms, 内存消耗: 5236K, 提交时间: 2019-10-28 19:33:14
#include<bits/stdc++.h> using namespace std; const int N=3e5+100; #define ll long long ll c[N]; void add(int x) { while(x<N) { c[x]++; x+=x&-x; } } ll query(int x) { ll ans=0; while(x) { ans+=c[x]; x-=x&-x; } return ans; } int main() { int n; cin>>n; for(int i=1;i<=n;i++) { int op; cin>>op; if(op==1) { double x,y,z; cin>>x>>y>>z; add(ceil(sqrt(x*x+y*y+z*z))); } else { int k; cin>>k; int l=0,r=2e5+10; while(l<r) { ll mid=l+r>>1; if(query(mid)>=k) r=mid; else l=mid+1; } if(l==2e5+10) cout<<-1<<endl; else cout<<l<<endl; } } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 656ms, 内存消耗: 5016K, 提交时间: 2019-10-28 13:11:56
#include<iostream> #include<cmath> using namespace std; long long n,x,y,z,p,k,c[300005],mid,ans; void find(int x) { for(;x<=300000;x+=(x&-x)) c[x]++; return ; } int get(int x) { int s=0; for(;x;x-=(x&-x)) s+=c[x]; return s; } int main() { cin>>n; while(n--) { cin>>p; if(p==1) { cin>>x>>y>>z; find((int)(sqrt(x*x+y*y+z*z)+0.99999999)); } else { cin>>k; int mid,l=0,r=300000; ans=-1; while(l<=r) { mid=(l+r)/2; if(get(mid)>=k) r=(ans=mid)-1; else l=mid+1; } cout<<ans<<"\n"; } } }