CF# Educational Codeforces Round 3 F. Frogs and mosquitoes

F. Frogs and mosquitoes
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

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.

Sample test(s)
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

 题意:给出n只青蛙,m只蚊子,每只青蛙有一个舌头长度。蚊子一只一只的出现,如果这只蚊子在青蛙的右边,且距离不超过青蛙的舌头长度,那么这只青蛙是可以吃掉这只蚊子的。如果有多只青蛙可以吃掉同一只蚊子,那么最左端的青蛙吃掉这只蚊子。

只有当青蛙吃完或者无法再吃在现场的蚊子时,下一只蚊子才会出现。

问,每只蚊子最后的舌头长度,和吃掉的蚊子数。

分析:我们可以把每只青蛙可以吃掉的范围抽象成线段,然后蚊子就相当于延长某一条线段,然后维护这些线段即可。

  1 /**
  2 Create By yzx - stupidboy
  3 */
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <cmath>
  8 #include <deque>
  9 #include <vector>
 10 #include <queue>
 11 #include <iostream>
 12 #include <algorithm>
 13 #include <map>
 14 #include <set>
 15 #include <ctime>
 16 #include <iomanip>
 17 using namespace std;
 18 typedef long long LL;
 19 typedef double DB;
 20 #define MIT (2147483647)
 21 #define INF (1000000001)
 22 #define MLL (1000000000000000001LL)
 23 #define sz(x) ((int) (x).size())
 24 #define clr(x, y) memset(x, y, sizeof(x))
 25 #define puf push_front
 26 #define pub push_back
 27 #define pof pop_front
 28 #define pob pop_back
 29 #define mk make_pair
 30 
 31 inline int Getint()
 32 {
 33     int Ret = 0;
 34     char Ch = ' ';
 35     bool Flag = 0;
 36     while(!(Ch >= '0' && Ch <= '9'))
 37     {
 38         if(Ch == '-') Flag ^= 1;
 39         Ch = getchar();
 40     }
 41     while(Ch >= '0' && Ch <= '9')
 42     {
 43         Ret = Ret * 10 + Ch - '0';
 44         Ch = getchar();
 45     }
 46     return Flag ? -Ret : Ret;
 47 }
 48 
 49 const int N = 200010;
 50 int n, m;
 51 struct Frogs
 52 {
 53     int left, right, index;
 54     Frogs(){}
 55     Frogs(int l, int r, int idx)
 56     {
 57         left = l, right = r, index = idx;
 58     }
 59     
 60     inline bool operator <(const Frogs &t) const
 61     {
 62         if(left != t.left) return left < t.left;
 63         if(right != t.right) return right < t.right;
 64         return index < t.index;
 65     }
 66 } arr[N];
 67 set<Frogs> store;
 68 int number[N];
 69 LL ans[N];
 70 struct Mosquito
 71 {
 72     int pos, size;
 73     Mosquito() {}
 74     Mosquito(int p, int s)
 75     {
 76         pos = p, size = s;
 77     }
 78     
 79     inline bool operator <(const Mosquito &t) const
 80     {
 81         if(pos != t.pos) return pos < t.pos;
 82         return size < t.size;
 83     }
 84 } ;
 85 multiset<Mosquito> que;
 86 
 87 inline void Insert(int left, int right, int index)
 88 {
 89     Frogs t = Frogs(left, 0, 0);
 90     if(!store.empty())
 91     {
 92         set<Frogs>::iterator it = store.lower_bound(t);
 93         while(it != store.end())
 94         {
 95             if(it->left > right) break;
 96             if(it->right <= right) store.erase(it);
 97             else
 98             {
 99                 Frogs tn = *it;
100                 tn.left = right + 1;
101                 store.erase(it);
102                 store.insert(tn);
103             }
104             it = store.lower_bound(t);
105         }
106     }
107     
108     t = Frogs(left, right, index);
109     store.insert(t);
110 }
111 
112 inline void Input()
113 {
114     n = Getint();
115     m = Getint();
116     for(int i = 1; i <= n; i++)
117     {
118         int pos = Getint();
119         int len = Getint();
120         ans[i] = len, number[i] = 0;
121         arr[i].left = pos, arr[i].right = pos + len, arr[i].index = i;
122     }
123 }
124 
125 inline bool Eaten(int pos, int size)
126 {
127     if(store.empty()) return 0;
128     set<Frogs>::iterator it = store.lower_bound(Frogs(pos, 0, 0));
129     if(it == store.end()) it--;
130     else if(it->left > pos)
131     {
132         if(it == store.begin()) return 0;
133         it--;
134     }
135     
136     if(it->right < pos) return 0;
137     Frogs t = *it;
138     store.erase(it);
139     t.right += size;
140     t.right = min(t.right, INF);
141     number[t.index]++, ans[t.index] += size;
142     set<Mosquito>::iterator mos = que.lower_bound(Mosquito(t.left, 0));
143     while(mos != que.end())
144     {
145         if(mos->pos > t.right) break;
146         t.right += mos->size;
147         t.right = min(t.right, INF);
148         number[t.index]++, ans[t.index] += mos->size;
149         que.erase(mos);
150         mos = que.lower_bound(Mosquito(t.left, 0));
151     }
152     Insert(t.left, t.right, t.index);
153     return 1;
154 }
155 
156 inline void Solve()
157 {
158     int rightmost = -1;
159     sort(arr + 1, arr + 1 + n);
160     for(int i = 1; i <= n; i++)
161         if(rightmost < arr[i].right)
162         {
163             Insert(max(arr[i].left, rightmost + 1), arr[i].right, arr[i].index);
164             rightmost = arr[i].right;
165         }
166     
167     while(m--)
168     {
169         int pos = Getint();
170         int size = Getint();
171         if(!Eaten(pos, size))
172             que.insert(Mosquito(pos, size));
173     }
174     
175     for(int i = 1; i <= n; i++) printf("%d %I64d\n", number[i], ans[i]);
176 }
177 
178 int main()
179 {
180     freopen("a.in", "r", stdin);
181     freopen("a.out", "w", stdout);
182     Input();
183     Solve();
184     return 0;
185 }
View Code

 

posted @ 2015-12-22 22:10  yanzx6  阅读(410)  评论(0编辑  收藏  举报