Codeforces Round #327
【Codeforces Round #336】

【Educational Codeforces Round 3 F】 Frogs and mosquitoes

Zarxdy34 posted @ 2015年12月22日 21:12 in Codeforces with tags 线段树 set , 549 阅读

  这道题稍微有点难度...本来想强行敲Splay的,但写C的时候逗比了没时间。然后下面大概地负数一下官方题解。

  首先按照青蛙的坐标排序,并建立一棵线段树,线段树上的每一个节点记录一只青蛙能吃到的蚊子的范围(ai,bi),维护子树中bi的最大值。

  然后用一个multiset(注意是multiset!因为蚊子的位置可能是重叠的)记录没有被吃到的蚊子。

  对于每一只新来的蚊子,找到能吃掉它的最左边的那只青蛙(吃不掉就直接加进集合里),吃掉后青蛙这只青蛙的b变大,并在set里继续找坐标不小于原来的蚊子的蚊子,一直吃。

  关于找青蛙的操作,一种是二分青蛙的坐标x,找到那些坐标<=x的青蛙中b的最大值是否>=当前蚊子的坐标,这样的时间复杂度是O(nlog^2n)的;第二种方法是直接在线段树上找,如果左子树里最大的b>=当前蚊子坐标,则只在左子树中找,否则在右子树中找。因为如果左子树符合那个条件却找不到的话,那么右子树中是一定找不到的。

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
const int maxn=200010;

struct Frog {int x,t,id;}F[maxn];
bool cmp (const Frog &a,const Frog &b) {return a.x<b.x;}
struct Mosquito {int p,b;Mosquito(int _p,int _b):p(_p),b(_b){} bool operator< (const Mosquito &b) const {return p<b.p;}};
typedef multiset<Mosquito>::iterator Mit;
multiset <Mosquito> M;

struct Segment_Tree
{
	LL a[maxn<<2],b[maxn<<2];
	int eated[maxn<<2];
	int pos[maxn],rank[maxn];
	int n;

	#define ls (o<<1)
	#define rs ((o<<1)|1)
	#define mid ((l+r)>>1)

	void Update(int o) {b[o]=max(b[ls],b[rs]);}

	void Build(int o,int l,int r,Frog *Frogs)
	{
		if (l==r) {rank[Frogs[l].id]=o;pos[l]=o;a[o]=Frogs[l].x;b[o]=Frogs[l].t+a[o];return;}
		Build(ls,l,mid,Frogs);
		Build(rs,mid+1,r,Frogs);
		Update(o);
	}
	
	int Query(int o,int l,int r,LL x)
	{
		if (l==r) if (a[o]>x || b[o]<x) return 0;else return l;
		if (b[ls]>=x) return Query(ls,l,mid,x);
		else return Query(rs,mid+1,r,x);
	}
	
	void Change(int x,int t)
	{
		int o=pos[x];
		b[o]+=t;
		eated[o]++;
		while (o>>=1) Update(o);
	}
	
	void Print() {for (int i=1;i<=n;i++) printf("%d %I64d\n",eated[rank[i]],b[rank[i]]-a[rank[i]]);}
	int Query(int x) {return Query(1,1,n,(LL)x);}
	#undef ls
	#undef rs
	#undef mid
}T;

int n,m;

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d%d",&F[i].x,&F[i].t),F[i].id=i;
	sort(F+1,F+1+n,cmp);
	T.Build(1,1,n,F);T.n=n;
	for (int i=1,p,b;i<=m;i++)
	{
		scanf("%d%d",&p,&b);
		Mosquito temp=Mosquito(p,b);
		M.insert(temp);
		Mit eatmos=M.find(temp);
		int eatfrog;
		while (eatmos!=M.end() && (eatfrog=T.Query((*eatmos).p)))
		{
			T.Change(eatfrog,temp.b);
			M.erase(eatmos);
			eatmos=M.lower_bound(temp);
			temp=*eatmos;
		}
	}
	T.Print();
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter