P9571 题解
思路
先发个和题解区其它题解不一样的思路。
这题我们可以定义一个变量 ,代表当前的直线数量。再定义一个 map 变量 ,其中 表示题目中的 为 的直线数量。最后定义一个 map 套 map 变量 (当然你也可以用 map <pair <int, int>, int> 的形式),其中 表示 为 且 为 的直线数量。
我们设 是问题类型,当 时,我们只要对 分别加上 即可。
当 时,题目要求恰好有一个公共点。而要使一条直线恰好与要求的直线只有一个公共点,则要使两条直线是不平行的,即 不相等,所以答案就成了 。
当 时,题目要求至少有一个公共点。而要使一条直线至少与要求的直线一个公共点,则要使两条直线是不平行的,或是两条线完全重合,即 不相等,或是 与 都相等,所以我们在更改的时候可以先设一个临时的 map 变量 ,用于存储 ,因为只有 才可能被保留。而直线总数 变成了 。接着,我们把 和 都清空了,把 赋为 ,因为只有 相同的才能保留下来。现在,我们把刚才存下来的 赋值到 里,并把 赋为 。
但是,提交后你会发现 TLE 在最后一个点了,为什么?因为清空太慢了,要知道,clear 函数可以 的!所以我们就干脆不清空了,开 个 map 套 map,反正只要没用过它就不会占空间。
但是你还是在最后一个点 MLE 了。看来占用的空间还是太多了,说明用的轮数(即 的次数)太多了,这时候我们考虑不要 clear 了,直接将 和 交换即可。这样,就 AC 了。
代码
# include <bits/stdc++.h>
using namespace std;
int n, op, k, b, sum, maxx, now;
map <int, int> tot[100005];
map <int, map <int, int>> mp[100005];
int main () {
cin >> n;
while (n --) {
cin >> op >> k >> b;
if (op < 2)
++ tot[now][k], ++ sum, ++ mp[now][k][b];
else if (op < 3)
cout << sum - tot[now][k] << '\n';
else
++ now, swap (mp[now][k], mp[now - 1][k]), tot[now][k] = sum = tot[now - 1][k] - mp[now][k][b], mp[now][k][b] = 0;
}
return 0;
}

浙公网安备 33010602011771号