其他分享
首页 > 其他分享> > codeforces 609F Frogs and mosquitoes 线段树+二分+multiset

codeforces 609F Frogs and mosquitoes 线段树+二分+multiset

作者:互联网

http://codeforces.com/problemset/problem/609/F
There are n frogs sitting on the coordinate axis Ox. For each frog two values xi, ti are known — the position and the initial length of the tongue of the i-th frog (it is guaranteed that all positions xi are different). m mosquitoes one by one are landing to the coordinate axis. For each mosquito two values are known pj — the coordinate of the position where the j-th mosquito lands and bj — the size of the j-th mosquito. Frogs and mosquitoes are represented as points on the coordinate axis.

The frog can eat mosquito if mosquito is in the same position with the frog or to the right, and the distance between them is not greater than the length of the tongue of the frog.

If at some moment several frogs can eat a mosquito the leftmost frog will eat it (with minimal xi). After eating a mosquito the length of the tongue of a frog increases with the value of the size of eaten mosquito. It's possible that after it the frog will be able to eat some other mosquitoes (the frog should eat them in this case).

For each frog print two values — the number of eaten mosquitoes and the length of the tongue after landing all mosquitoes and after eating all possible mosquitoes by frogs.

Each mosquito is landing to the coordinate axis only after frogs eat all possible mosquitoes landed before. Mosquitoes are given in order of their landing to the coordinate axis.

Input

First line contains two integers n, m (1 ≤ n, m ≤ 2·105) — the number of frogs and mosquitoes.

Each of the next n lines contains two integers xi, ti (0 ≤ xi, ti ≤ 109) — the position and the initial length of the tongue of the i-th frog. It is guaranteed that all xi are different.

Next m lines contain two integers each pj, bj (0 ≤ pj, bj ≤ 109) — the position and the size of the j-th mosquito.

Output

Print n lines. The i-th line should contain two integer values ci, li — the number of mosquitoes eaten by the i-th frog and the length of the tongue of the i-th frog.

Examples
Input

4 6
10 2
15 0
6 1
0 1
110 10
1 1
6 0
15 10
14 100
12 2

Output

3 114
1 10
1 1
1 2

Input

1 2
10 2
20 2
12 1

Output

1 3

题目大意:给出nnn只青蛙的位置pos1pos1pos1和舌头长度lenlenlen,给出mmm只蚊子的位置pos2pos2pos2和sizesizesize,认为青蛙和蚊子都在一条线上且把它们当成点来处理,如果满足条件:pos1&lt;=pos2&lt;=pos1+lenpos1&lt;=pos2&lt;=pos1+lenpos1<=pos2<=pos1+len,则这只蚊子可以被青蛙吃掉,同时青蛙的舌头长度变为:len+=sizelen+=sizelen+=size。蚊子是按照顺序一只一只的落在线上的,当且仅当前面的蚊子都已经被吃掉了或者无法被吃掉,下一只蚊子才会落下来。而且如果有多只青蛙能吃到该蚊子,则一定是最左侧的青蛙吃掉该蚊子。请输出每只青蛙最终吃掉的蚊子数量ansansans以及舌头的最终长度lenlenlen。
思路:半年前看不懂题解的题现在终于能看懂题解了。对于每只蚊子要选择能吃掉它的且最靠左的青蛙,怎么求这只青蛙呢。首先我们需要把青蛙按照坐标从小到大排序,然后我们用线段树维护pos1+lenpos1+lenpos1+len的最大值,那么我们需要找到一个最小的iii满足query(1,i)&gt;=pos2query(1,i)&gt;=pos2query(1,i)>=pos2。(query(1,i)query(1,i)query(1,i)表示查询排序后第111只青蛙到第iii只青蛙的pos1+lenpos1+lenpos1+len的最大值)线段树+二分可以找到这个iii。但是题目给的坐标范围太大了,因此我们需要离散一下,记录一下每只青蛙的初始下标indexindexindex就好了。对于每只蚊子,我们先判断一下它能不能被吃掉,如果不能的话就把他的位置记录在multisetmultisetmultiset中(因为可能有多只蚊子在同一位置),如果能吃掉的话,就更新ansansans和lenlenlen,同时还要判断这只青蛙的舌头变长后是不是能吃掉原来吃不到的青蛙。如果能的话,继续更新下去就好了。详见代码注释。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define pr pair<long,long>
using namespace std;
typedef long long ll;

const int maxn=2e5+5;

struct node
{
    ll pos,len;
    int id;
    bool operator <(const node &a)const
    {
        return pos<a.pos;
    }
}a[maxn];

struct T
{
    int l,r;
    ll MAX;
}tree[maxn<<2];
pr mos[maxn];//记录蚊子的坐标和size
int ans[maxn];//记录青蛙吃到的蚊子数量
ll len[maxn];//记录青蛙的舌头长度
ll x[maxn];//记录青蛙的坐标
int n,m;

void build(int i,int l,int r)
{
    tree[i].l=l,tree[i].r=r;
    if(l==r)
    {
        tree[i].MAX=a[l].pos+a[l].len;
        return ;
    }
    int mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    tree[i].MAX=max(tree[i<<1].MAX,tree[i<<1|1].MAX);
}

ll query(int i,int l,int r)
{
    if(tree[i].l==l&&tree[i].r==r)
        return tree[i].MAX;
    int mid=(tree[i].l+tree[i].r)>>1;
    if(r<=mid)
        return query(i<<1,l,r);
    else if(l>mid)
        return query(i<<1|1,l,r);
    else
        return max(query(i<<1,l,mid),query(i<<1|1,mid+1,r));
}

void update(int i,int pos,ll v)
{
    if(tree[i].l==tree[i].r)
    {
        tree[i].MAX+=v;
        return ;
    }
    int mid=(tree[i].l+tree[i].r)>>1;
    if(pos<=mid)
        update(i<<1,pos,v);
    else
        update(i<<1|1,pos,v);
    tree[i].MAX=max(tree[i<<1].MAX,tree[i<<1|1].MAX);
}

int solve(ll pos)//找能吃到pos这个位置的蚊子的最左侧的青蛙
{
    int l=1,r=upper_bound(x+1,x+1+n,pos)-x-1;
    if(r==0||query(1,1,r)<pos)//吃不到
        return -1;
    int mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(query(1,1,mid)<pos)
            l=mid+1;
        else
            r=mid-1;
    }
    return l;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&a[i].pos,&a[i].len),a[i].id=i;
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
        x[i]=a[i].pos;
    for(int i=1;i<=m;i++)
        scanf("%lld%lld",&mos[i].first,&mos[i].second);
    build(1,1,n);
    multiset<pr> s;
    for(int i=1;i<=m;i++)
    {
        int pos=solve(mos[i].first);
        if(pos==-1)//暂时没有青蛙能吃到这只蚊子
            s.insert(mos[i]); //插入到set集合中
        else//有青蛙能吃到这只蚊子
        {
            ans[a[pos].id]++;//记录这只青蛙吃到的蚊子数量
            a[pos].len+=mos[i].second;//青蛙的舌头长度增加
            update(1,pos,mos[i].second);
            ll tmp=a[pos].pos+a[pos].len;//这只青蛙能吃到的最靠右侧的蚊子
            while(!s.empty())//看这只青蛙是不是能吃到以前不能吃到的蚊子
            {
                multiset<pr>:: iterator it=s.lower_bound(pr(a[pos].pos,0));//找到在这只青蛙右侧的第一只蚊子
                if(it==s.end()||it->first>tmp)//没有找到或者这只蚊子太远了 还是吃不到
                    break;
                tmp+=it->second;//该青蛙现在能吃到这只蚊子了
                ans[a[pos].id]++;//更新数量
                a[pos].len+=it->second;//更新长度
                update(1,pos,it->second);
                s.erase(it);//从set中删去这只蚊子
            }
        }
    }
    for(int i=1;i<=n;i++)
        len[a[i].id]=a[i].len;
    for(int i=1;i<=n;i++)
        printf("%d %lld\n",ans[i],len[i]);
    return 0;
}

标签:Frogs,蚊子,青蛙,frog,codeforces,mosquito,th,mosquitoes
来源: https://blog.csdn.net/xiji333/article/details/99078793