题目 | Climbing the Tree
CodeTON Round 4 (Div. 1 + Div. 2, Rated, Prizes!)
D. Climbing the Tree
https://codeforces.com/contest/1810/problem/D
2 seconds / 256 megabytes
standard input / standard output
Problem
The snails are climbing a tree. The tree height is
Each snail has two attributes
Unfortunately, you don't know the exact tree height
- Event of type
: a snail with attributes , comes and claims that he spent days climbing the tree. If this message contradicts previously adopted information (i. e. there is no tree for which all previously adopted statements and this one are true), ignore it. Otherwise, adopt it. - Event of type
: a snail with attributes , comes and asks you how many days he will spend if he climbs the tree. You can only give the answer based on the information you have adopted so far. If you cannot determine the answer precisely, report that.
You need to deal with all the events in order.
Input
Each test contains multiple test cases. The first line contains a single integer
The first line of each test case contains one integer
For the following
If the event type is
If the event type is
It is guaranteed that the sum of
Output
For each test case, output
- for each event of type
, if you adopt the message, output ; if you ignore it, output ; - for each event of type
, output an integer denoting the number of days that the snail will spend. If you cannot determine it, output .
Example
Input
5
3
1 3 2 5
2 4 1
2 3 2
3
1 6 5 1
2 3 1
2 6 2
3
1 4 2 2
1 2 1 3
2 10 2
9
1 7 3 6
1 2 1 8
2 5 1
1 10 9 7
1 8 1 2
1 10 5 8
1 10 7 7
2 7 4
1 9 4 2
9
1 2 1 6
1 8 5 6
1 4 2 7
2 9 1
1 5 1 4
1 5 2 7
1 7 1 9
1 9 1 4
2 10 8
Output
1 2 5
1 -1 1
1 0 1
1 0 -1 0 0 0 1 8 0
1 0 0 1 0 0 0 0 1
Note
In the first test case, we can determine
Let's show how the second snail climbs:
- During the daylight hours of the
st day: climbs up meters, now at position . - During the night of the
st day: slides down meters, now at position . - During the daylight hours of the
nd day: climbs up meters, now at position (reaches the top).
In the third test case, the second snail's message contradicts the first snail's, because the second snail says he spent
题解
整体框架
维护一个对树的高度的预测值区间
收到信息(事件
):通过给定的 ,计算出新的树高预测值 ,若 (即 或 ):新信息与已有信息矛盾,拒绝该信息。 :新信息与已有信息不矛盾,接受该信息,更新 .
收到询问(事件
):通过给定的 ,判断爬到 需要的天数 ,爬到 需要的天数 ,若 :则能够确定爬上树需要的天数为 . :无法确定爬上树需要的天数具体为多少。
上述框架的思路应该比较清晰,该题难点在于如何使用给定信息计算出对应的数据,过程中也有很多坑点。
预测树高
如何通过给定的
由题意得,
我们令
(也可以写做 )
易错点:
若
所以
预测天数
如何通过给定的
我们知道,最后一天如果爬上树了,就不会再下滑了,这给我们编程带来了一点麻烦。
为了将问题统一化,我们不妨让最后一天也会下滑,那么问题就能看做:每天向上爬
这个问题就很简单了:
向上取整的实现方式可以参考以下两种:
易错点:区间是左开右闭的
我们的树高区间为
代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
void solve()
{
int q;
cin >> q;
int lb = 1, ub = 1e18;
while (q--)
{
int op;
cin >> op;
if (op == 1)
{
int a, b, n;
cin >> a >> b >> n;
int delta = a - b;
int _lb, _ub;
if (n == 1)
{
_lb = 0;
_ub = a;
}
else
{
_lb = delta * (n - 1) + b;
_ub = delta * (n - 1) + a;
}
if (_lb >= ub || _ub <= lb)
{
cout << 0 << ' ';
continue;
}
lb = max(lb, _lb);
ub = min(ub, _ub);
cout << 1 << ' ';
}
else // if (op == 2)
{
int a, b;
cin >> a >> b;
int delta = a - b;
int _min = max(1LL, ((lb + 1) - b + (delta - 1)) / delta);
int _max = max(1LL, (ub - b + (delta - 1)) / delta);
if (_min == _max)
cout << _min << ' ';
else
cout << -1 << ' ';
}
}
cout << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi
so Strong