登录
OAmaster

Given an integer array arr[n] and an integer d, count the number of distinct triplets (i, j, k) where 0 <= i < j < k < n and arr[i] + arr[j] + arr[k] is divisible by d.

Example: arr = [2, 3, 1, 6], d = 32 (triplets (0,1,2) and (0,2,3)).

Constraints

3 ≤ n ≤ 10³, 1 ≤ arr[i] ≤ 10⁹, 2 ≤ d ≤ 10⁶.

解法

统计模 d 各余数的频次,再求满足 r1 + r2 + r3 ≡ 0 (mod d) 的有序三元组数。重复余数用二项系数处理。复杂度 O(n + d²)

from math import comb

def get_triplet_count(a, d):
    cnt = [0] * d
    for x in a:
        cnt[x % d] += 1
    ans = 0
    for r1 in range(d):
        for r2 in range(r1, d):
            r3 = (d - (r1 + r2) % d) % d
            if r3 < r2:
                continue
            if r1 == r2 == r3:
                ans += comb(cnt[r1], 3)
            elif r1 == r2:
                ans += comb(cnt[r1], 2) * cnt[r3]
            elif r2 == r3:
                ans += cnt[r1] * comb(cnt[r2], 2)
            else:
                ans += cnt[r1] * cnt[r2] * cnt[r3]
    return ans
class Solution {
    static long getTripletCount(int[] a, int d) {
        long[] cnt = new long[d];
        for (int x : a) cnt[((x % d) + d) % d]++;
        long ans = 0;
        for (int r1 = 0; r1 < d; r1++)
            for (int r2 = r1; r2 < d; r2++) {
                int r3 = ((d - (r1 + r2) % d) % d);
                if (r3 < r2) continue;
                if (r1 == r2 && r2 == r3) ans += cnt[r1] * (cnt[r1] - 1) * (cnt[r1] - 2) / 6;
                else if (r1 == r2) ans += cnt[r1] * (cnt[r1] - 1) / 2 * cnt[r3];
                else if (r2 == r3) ans += cnt[r1] * cnt[r2] * (cnt[r2] - 1) / 2;
                else ans += cnt[r1] * cnt[r2] * cnt[r3];
            }
        return ans;
    }
}
#include <vector>
using namespace std;

long long getTripletCount(vector<int>& a, int d) {
 vector<long long> cnt(d, 0);
 for (int x : a) cnt[((x % d) + d) % d]++;
 long long ans = 0;
 for (int r1 = 0; r1 < d; r1++)
 for (int r2 = r1; r2 < d; r2++) {
 int r3 = ((d - (r1 + r2) % d) % d);
 if (r3 < r2) continue;
 if (r1 == r2 && r2 == r3) ans += cnt[r1] * (cnt[r1] - 1) * (cnt[r1] - 2) / 6;
 else if (r1 == r2) ans += cnt[r1] * (cnt[r1] - 1) / 2 * cnt[r3];
 else if (r2 == r3) ans += cnt[r1] * cnt[r2] * (cnt[r2] - 1) / 2;
 else ans += cnt[r1] * cnt[r2] * cnt[r3];
 }
 return ans;
}

Two integers are considered coprime if their greatest common divisor (GCD) is 1.

Given an array A of positive integers, return an array B of length len(A) where B[i] represents the count of integers in [1, A[i]] (inclusive) that are co-prime with A[i].

Example: A = [5, 8, 14]B = [4, 4, 6].

Constraints

1 ≤ A[i] ≤ 10⁵.

解法

B[i] 即欧拉函数 φ(A[i])。对每个值用 sqrt(A[i]) 内的试除分解质因数,再套 φ(n) = n · Π(1 − 1/p)。复杂度 O(n · sqrt(max A))

def coprime_count(A):
    def phi(n):
        result = n
        p = 2
        while p * p <= n:
            if n % p == 0:
                while n % p == 0:
                    n //= p
                result -= result // p
            p += 1
        if n > 1:
            result -= result // n
        return result
    return [phi(x) for x in A]
class Solution {
    static int phi(int n) {
        int res = n;
        for (int p = 2; (long) p * p <= n; p++) {
            if (n % p == 0) {
                while (n % p == 0) n /= p;
                res -= res / p;
            }
        }
        if (n > 1) res -= res / n;
        return res;
    }
    static int[] coprimeCount(int[] A) {
        int[] out = new int[A.length];
        for (int i = 0; i < A.length; i++) out[i] = phi(A[i]);
        return out;
    }
}
#include <vector>
using namespace std;

int phi(int n) {
 int res = n;
 for (int p = 2; (long long) p * p <= n; p++) {
 if (n % p == 0) {
 while (n % p == 0) n /= p;
 res -= res / p;
 }
 }
 if (n > 1) res -= res / n;
 return res;
}

vector<int> coprimeCount(vector<int>& A) {
 vector<int> out;
 out.reserve(A.size());
 for (int x : A) out.push_back(phi(x));
 return out;
}

A trading firm predicts stock prices of a commodity for the next n days. A period of consecutive days is investable if the maximum price in the period is max_price and the minimum price is min_price. Given price[n], count the number of subarrays whose max equals max_price and min equals min_price.

Example: price = [1, 2, 3, 2], max_price = 3, min_price = 23 (subarrays [2,3], [2,3,2], [3,2]).

解法

枚举左端点 l,右端点 r 向右延伸,维护当前最大/最小值;越界提前停止,两端都满足则计数。复杂度 O(n²)

def count_investable_periods(price, mx, mn):
    n = len(price)
    cnt = 0
    for l in range(n):
        cur_max = cur_min = price[l]
        for r in range(l, n):
            cur_max = max(cur_max, price[r])
            cur_min = min(cur_min, price[r])
            if cur_max > mx or cur_min < mn:
                break
            if cur_max == mx and cur_min == mn:
                cnt += 1
    return cnt
class Solution {
    static long countInvestablePeriods(int[] price, int mx, int mn) {
        int n = price.length;
        long cnt = 0;
        for (int l = 0; l < n; l++) {
            int curMax = price[l], curMin = price[l];
            for (int r = l; r < n; r++) {
                curMax = Math.max(curMax, price[r]);
                curMin = Math.min(curMin, price[r]);
                if (curMax > mx || curMin < mn) break;
                if (curMax == mx && curMin == mn) cnt++;
            }
        }
        return cnt;
    }
}
#include <vector>
#include <algorithm>
using namespace std;

long long countInvestablePeriods(vector<int>& price, int mx, int mn) {
 int n = price.size();
 long long cnt = 0;
 for (int l = 0; l < n; l++) {
 int curMax = price[l], curMin = price[l];
 for (int r = l; r < n; r++) {
 curMax = max(curMax, price[r]);
 curMin = min(curMin, price[r]);
 if (curMax > mx || curMin < mn) break;
 if (curMax == mx && curMin == mn) cnt++;
 }
 }
 return cnt;
}
Pro 会员

解锁剩余 23 道 OA 真题

开通后立即解锁完整题面 + Python / Java / C++ 三语题解。 全站 165 家公司 · 1000+ 道 OA · 月度更新。