第 89 场双周赛
比赛链接
A 删除字符使频率相同
暴力删除每一种字符,然后哈希表判断是否符合题意。
复杂度 \(O(n^2)\)
B 最长上传前缀
使用一个哈希表记录出现过的数字,然后用一个数字表示当前最长上传前缀。每次返回前更新该变量即可。
时间复杂度 \(O(n)\)
C 所有数对的异或和
设两个数组长度分别为 \(n\) 和 \(m\),如果 \(m\) 为奇数,那么任意一个 \(nums2[1]\) 都会出现奇数次。\(nums2[i]\) 同理。
D 满足不等式的数对数目
将条件移项后可得:
\(nums1[i] - nums2[i] \le nums1[j] - nums2[j] + diff\)
因此,维护所有 \(nums1[i] - nums2[i]\) 的个数,放在「线段树」或者离散化后的「树状数组」中。
每次查询,二分找到位置,去查询即可。
时间复杂度 \(O(n\log n)\)。
| template <typename T>
struct Fenwick {
const int n;
vector<T> a;
Fenwick(int n): n(n), a(n + 1) {}
void add(int x, T v){
for(int i = x; i <= n; i += i & -i) a[i] += v;
}
T sum(int x) {
T rs = 0;
for(int i = x; i; i -= i & -i) {
rs += a[i];
}
return rs;
}
T rangeSum(int l, int r) {
if(l > r) return 0;
return sum(r) - sum(l - 1);
}
};
class Solution {
public:
using ll = long long;
long long numberOfPairs(vector<int>& nums1, vector<int>& nums2, int diff) {
int n = nums1.size();
vector<int> vals;
for (int i = 0; i < n; i++) {
vals.push_back(nums1[i] - nums2[i]);
}
sort(vals.begin(), vals.end());
int m = vals.size();
Fenwick<int> fen(m);
ll res = 0;
for (int i = 0; i < n; i++) {
int pos = upper_bound(vals.begin(), vals.end(), nums1[i] - nums2[i] + diff) - vals.begin();
res += fen.sum(pos);
pos = lower_bound(vals.begin(), vals.end(), nums1[i] - nums2[i]) - vals.begin() + 1;
fen.add(pos, 1);
}
return res;
}
};
|
本文访问 次