[Codeforces] 198E. Gripping Story

題目連結:http://codeforces.com/contest/198/problem/E
被雷了才會QQ
會發現其實他是個圓並不重要,重要的其實是距離,所以不妨把每個人的座標轉換成跟原點的距離,這樣的話每次詢問就變成詢問一個距離內質量小於k的數有誰,而我們其實也不用一次把一坨東西拉出來,只要一次拉一個就好,反正最多拉n個,複雜度不會太慘。而這樣其實就是詢問一個前綴極值就可達到這件事,所以就開個BIT套個單調的queue之類的就可以做到這件事了。
#include <bits/stdc++.h>
using namespace std;
typedef long long lld;
#define PB push_back
#define ALL(x) begin(x), end(x)
#define FF first
#define SS second
const int N = 250000 + 5;
const lld INF = 1LL<<31;

class LiSan{
	private:
		vector<lld> vv;
	public:
		inline void init(){vv.clear();}
		inline void insert(lld x){vv.PB(x);}
		inline void done(){
			sort(ALL(vv));
			vv.resize(distance(vv.begin(), unique(ALL(vv))));
		}
		inline int size(){return vv.size();}
		inline int get(lld x){
			return distance(vv.begin(), lower_bound(ALL(vv), x));
		}
		inline lld inv_get(int x){return vv[x];}
} lisan;

struct Obj{
	lld d, m, p, r;
	bool operator<(const Obj &x) const {
		return tie(m, d) < tie(x.m, x.d);
	}
} arr[N];

class BIT{
	typedef pair<Obj, int> node;
	private:
		bool removed[N];
		queue<node> nodes[2*N];
		int n;
		inline int lowbit(int x){return x&(-x);}
	public:
		void init(int _n){
			n=_n;
			memset(removed, 0, sizeof(removed));
			fill(nodes, nodes+n, queue<node>());
		}
		void add(int p, node x){
			while(p<n){
				nodes[p].push(x);
				p+=lowbit(p);
			}
		}
		node query(int x){
			node ret = {{INF, INF, INF, INF}, INF};
			while(x){
				while(!nodes[x].empty() and removed[nodes[x].front().SS])
					nodes[x].pop();
				if(!nodes[x].empty()) ret = min(ret, nodes[x].front());
				x-=lowbit(x);
			}
			return ret;
		}
		void erase(int id){
			removed[id]=1;
		}
} bit;

int main(){
	ios_base::sync_with_stdio(0);cin.tie(0);
	lisan.init();
	lld x, y, p, r, n; cin>>x>>y>>p>>r>>n;
	lisan.insert(0); lisan.insert(r*r);
	for(int i=0;i<n;i++){
		lld xx, yy; cin>>xx>>yy;
		cin>>arr[i].m>>arr[i].p>>arr[i].r;
		xx-=x, yy-=y;
		arr[i].d = xx*xx+yy*yy;
		arr[i].r*=arr[i].r;
		lisan.insert(arr[i].d);
		lisan.insert(arr[i].r);
	}
	lisan.done();
	bit.init(lisan.size()+3);
	sort(arr, arr+n);
	for(int i=0;i<n;i++) bit.add(lisan.get(arr[i].d), {arr[i], i});
	int ans = 0;
	queue<Obj> qq;
	qq.push({0, 0, p, r*r});
	while(!qq.empty()){
		auto cur = qq.front(); qq.pop();
		lld dd = lisan.get(cur.r);
		auto mm = bit.query(dd);
		while(mm.FF.m <= cur.p){
			ans++;
			bit.erase(mm.SS);
			qq.push(mm.FF);
			mm = bit.query(dd);
		}
	}
	cout<<ans<<'\n';
	return 0;
}

留言

這個網誌中的熱門文章

[TIOJ] 1271. [IOI 2012] Scrivener 斯克里夫尼

[TIOJ] 1429. [APIO '12] 忍者調度問題

[Codeforces] 731D. 80-th Level Archeology