ACdream 1127 Base Station (離線查詢+樹狀數組)
阿新 • • 發佈:2018-01-29
post double 查詢 else cdr unique ase 用戶 負責
題目鏈接:
http://acdream.info/problem?pid=1127
題目:
移動通信系統中,通信網的建立主要通過基站來完成。
基站可以分為主基站和子基站。子基站和各個移動用戶進行連接,子基站必須通過主基站來和外界實現通信。主基站可以覆蓋到的範圍是一個圓形區域,子基站和主基站的距離小於半徑r才能被該主基站覆蓋到。半徑r由主基站的發射功率確定。
某個區域的移動通信網,包含2個主基站和N個子基站。它們的位置都可以對應到一個整數坐標上。如果子基站至少被一個主基站覆蓋,則該子基站是激活的。
現在通信公司在調試設備,它們不停地改變主基站的發射功率,當兩個主基站的覆蓋半徑分別為r1和r2時,需要知道有多少個子基站處於非激活狀態。
題解:
對坐標進行轉化,子基站對到主基站1(x1,y1)的距離轉化為X軸,子基站對到主基站2(x2,y2)的距離轉化為Y軸。然後對( 子基站到主基站2(x2,y2)的距離和主基站2的覆蓋半徑) 進行離散化處理。
然後按X軸進行降序排序,最後將Y軸插入到樹狀數組中進行維護和離線查詢就行了。
負責度:\(O(m*logn)\)
代碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 2e5+100; const int mod = 1e9+7; struct node { int x,y; int id; bool operator < (const node &a) { return (x == a.x && id < a.id) || (x > a.x); } }node[maxn]; int num[maxn]; int ans[maxn]; map<int,int>mp; int sum[maxn]; int k; void update(int pos,int val){ // std::cout << "k=" << k << '\n'; while(pos<=k) { sum[pos]+=val; pos += (pos&-pos); } } int query(int pos) { int res = 0; while(pos) { res += sum[pos]; pos -= (pos&-pos); } return res; } double distance(double x1,double y1,double x2,double y2) { return (double)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main(int argc, char const *argv[]) { int x1,x2,y1,y2; int n,m,x,y; while(std::cin >> x1 >> y1 >> x2 >> y2) { mp.clear(); k = 0; std::cin >> n; for(int i=1;i<=n;i++) { std::cin >> x >> y; node[i].x = (int)distance(x,y,x1,y1); node[i].y = (int)distance(x,y,x2,y2); node[i].id = -i; num[k++] = node[i].y; } std::cin >> m; for(int i=1;i<=m;i++) { std::cin >> node[i+n].x >> node[i+n].y; node[i+n].id = i; num[k++] = node[i+n].y; } sort(num,num+k); k = unique(num,num+k)-num; for(int i=0;i<k;i++) { mp[num[i]] = i+1; } sort(node+1,node+n+m+1); memset(sum,0,sizeof( sum )); for(int i=1;i<=n+m;i++) { int pos = mp[node[i].y]; // std::cout << "now= " <<node[i].x<<" "<< node[i].y <<" " << node[i].id<<" " << pos << '\n'; if(node[i].id < 0) { update(pos,1); } else if(node[i].id >= 1){ ans[node[i].id] = query(k) - query(pos-1); } } for(int i=1;i<=m;i++) { std::cout << ans[i] << '\n'; } } // cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n"; return 0; }
ACdream 1127 Base Station (離線查詢+樹狀數組)