T15996. 统计数组中相等且可以被整除的数对
题目描述:给你一个长度为\(n\)的整数数组\(nums\),下标从\(0\)开始,问有多少下标\(i , j\)满足\(nums_i = nums_j , i \neq j , i *j \% k = 0\)。
数据范围:\(1 \leq n \leq 100\)
思路:数据范围很小,直接暴力即可
时间复杂度:\(O(n^2)\)
参考代码:
class Solution {
public:
int countPairs(vector<int>& nums, int k) {
int res = 0;
int n = nums.size();
for(int i = 0 ; i < n ; ++i){
for(int j = i + 1 ; j < n ; ++j){
if(nums[i] != nums[j]) continue;
if(i * j % k == 0) ++res;
}
}
return res;
}
};
T2 5997. 找到和为给定整数的三个连续整数
题目描述:给你一个整数\(n\),让你把其分解成三个连续的整数,若不存在分解方案,返回空数组。
思路:根据题意模拟即可
时间复杂度:\(O(1)\)
参考代码:
class Solution {
public:
vector<long long> sumOfThree(long long num) {
vector<long long>res;
if(num % 3 != 0) return res;
long long dx = num / 3;
for(long long i = dx - 1 ; i <= dx + 1 ; ++i) res.push_back(i);
return res;
}
};
T3 5998. 拆分成最多数目的偶整数之和
题目描述:给你一个整数\(n\),让你将其分解成不同偶数之和,要返回分解之后元素最多的方案,若不存在方案,返回空数组。
思路:显然奇数时不存在方案,特判。对于偶数,从\(2\)开始枚举,每次加\(2\),若剩余的数字减去当前枚举的数字后大于当前枚举的数字,那么把当前枚举的数字放入答案,剩余数字减去当前数字,否则将剩余数字放入答案,结束循环。
时间复杂度:\(O(\sqrt n)\)
参考代码:
class Solution {
public:
vector<long long> maximumEvenSplit(long long num) {
vector<long long> res;
if(num & 1) return res;
long long cur = 2;
while(num >= cur){
if(num - cur > cur){
res.push_back(cur);
num -= cur;
cur += 2;
}
else{
res.push_back(num);
break;
}
}
return res;
}
};
T4 5999. 统计数组中好三元组数目
题目描述:给你两个长度为\(n\)的排列\(P_1 , P_2\),统计满足下列条件的三元组的数量:
- \(P_1[pos_{u1}] = P_2[pos_{u2}]\)
- \(P_1[pos_{v1}] = P_2[pos_{v2}]\)
- \(P_1[pos_{w3}] = P_2[pos_{w3}]\)
- \(pos_{u1} < pos_{v1} < pos_{w1}\)
- \(pos_{u2} < pos_{v2} < pos_{w2}\)
思路:比较老套路的题,将其中一个排列映射成一个有序排列\(1...n\) 。那么原题就转化成对于另一个排列,其中满足:
- \(pos_x < pos_y < pos_z\)
- \(P_1[pos_x] < P_1[pos_y] < P_1[pos_z]\)
的三元组的数量。这也是一个经典题目,可以参考P1637 三元上升子序列。上述的转化思想可以参考P1439 【模板】最长公共子序列 。用两个树状数组或者线段树维护一下即可。
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
public:
long long goodTriplets(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
vector<int>f(n + 1 , 0);
for(int i = 1 ; i <= n ; ++i){
f[nums2[i - 1]] = i;
}
for(auto& num : nums1) num = f[num];
long long res = 0;
vector<int>tr1(n + 1 , 0) , tr2(n + 1 , 0);
auto lowbit = [](int x){return x & -x;};
auto add = [&](vector<int>& tr , int idx , int val)->void{
while(idx <= n){
tr[idx] += val;
idx += lowbit(idx);
}
return ;
};
auto getsum = [&](vector<int>& tr , int idx)->int{
int ans = 0;
while(idx){
ans += tr[idx];
idx -= lowbit(idx);
}
return ans;
};
for(auto num : nums1) add(tr1 , num , 1);
for(int i = 1 ; i <= n ; ++i){
int val = nums1[i - 1];
add(tr1 , val , -1);
int lr = getsum(tr2 , val), rs = n - i - getsum(tr1 , val - 1);
res += 1ll * lr * rs;
add(tr2 , val , 1);
}
return res;
}
};