1. 程式人生 > 實用技巧 >NC53370Forsaken的三維數點

NC53370Forsaken的三維數點

連結:https://ac.nowcoder.com/acm/problem/53370
來源:牛客網

題目描述

​ Forsaken現在在一個三維空間中,空間中每個點都可以用(x,y,z)(x,y,z)(x,y,z)表示。突然,三維空間的主人出現了,如果Forsaken想要繼續在三維空間中呆下去,他就必須回答三維空間主人的問題。

​ 主人會在空間中座標為(x,y,z)(x,y,z)(x,y,z)處加一點能量值,當他加了一定的次數之後,他會問Forsaken一個問題:如果座標(0,0,0)(0,0,0)(0,0,0)為球心,那麼至少需要多大的半徑才能使得球內的能量值總和大於或者等於kkk,在這裡,半徑為000也是可以的。這對於Forsaken來說實在是太難了,因此他把這個問題交給了你。

輸入描述:

第一行一個nnn表示操作的次數。
接下來每行首先一個整數opopop表示操作的種類。
如果op=1op = 1op=1,接下來333個整數x,y,zx,y,zx,y,z表示能量值增加的座標。
如果op=2op =2op=2,接下來一個整數kkk表示要求的能量值總和。

輸出描述:

對於每個op=2op=2op=2的操作,輸出一個整數表示球的半徑。(資料保證至少有一個222操作)
如果沒有滿足答案的半徑,輸出−1-1−1。

思路

題目要求是求空間內球體的半徑多長時可以符合能量值大於等於k的情況,這個時候由於輸出的是一個整數,也就是這個整數是來表示半徑的。

再加上題目求的是區間和,所以考慮樹狀陣列。

接下來為了使能夠構成樹狀陣列,在半徑可以回答0的情況時是無法構成樹狀陣列的,因為樹狀陣列是到達1處時求和就結束的。

所以我們給求出的每個半徑都+1就可以構成樹狀陣列了。

然後二分判斷情況。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;

#define int long long
const int maxn=1e6+10;
int k;

int d[maxn];

inline int lowbit(int x){return -x&x;}

void add(int x,int y){

    while(x<=200000){
        d[x]+=y;x+=lowbit(x);
    }

}

int get_sum(int x){
    int ans=0;
    while(x){
        ans+=d[x];x-=lowbit(x);
    }
    return ans;

}
signed main(){
    int m;
    cin>>m;
    while(m--){
        int x,y,z,op;
        cin>>op;
        if(op==1){
            cin>>x>>y>>z;
            add(ceil(sqrt(x*x+y*y+z*z))+1,1);
        }else{
            cin>>k;
            if(get_sum(200000)<k){
                cout<<-1<<endl;
            }else{
                int l=1,r=200000,mid;
                while(l<=r){
                    mid=l+r>>1;
                    if(get_sum(mid)>=k){
                        r=mid-1;
                    }else l=mid+1;
                }
                cout<<r<<endl;

            }

        }
    }


}