retarded_user
Senior Member
Bác ví dụ cách brute force đc kh?Q4 hồi đầu tưởng có gì đặc biệt ngồi tra mấy tính chất gcd, ngẫm lại thì brute force theo mấy ước của cái nums là ra mà code méo kịp cay vl
Bác ví dụ cách brute force đc kh?Q4 hồi đầu tưởng có gì đặc biệt ngồi tra mấy tính chất gcd, ngẫm lại thì brute force theo mấy ước của cái nums là ra mà code méo kịp cay vl
Mình 2 câu còn ăn bugs nữa chứ, nay code ngáo thật. Q2 cứ ngồi đần raContest này được 2 câu, mất điểm rồi![]()

cách e hình như cũng giống mấy cách mấy bác trên làm, cũngduyệt mấy ước của nums thêm vào cái mảng, r duyệt ngược lại để trừ bớt mấy cái bị trùng, sau đáp án thì upper_bound trên cái mảng lưu của bácBác ví dụ cách brute force đc kh?

class Solution {
public:
vector<int> gcdValues(vector<int>& nums, vector<long long>& queries) {
int mx = *max_element(nums.begin(), nums.end());
vector<long long> f(mx+1), cnt(mx+1);
for (auto&x:nums) f[x]++; // f[x] is the frequence of x appear in nums
for (int i = 1; i <= mx; i++) {
for (int j = i; j <= mx; j+=i){
cnt[i] += f[j];
}
}
// count number of num in nums that num % i == 0
for (int i = 1; i <= mx; i++) cnt[i] = cnt[i] * (cnt[i] - 1) / 2;
// count number of pair (i,j) (i < j) such that nums[i] % x == 0 nums[j] % x == 0
// i.e., cnt[x] = number of pair(i,j) (i < j) such that nums[i] % x == 0 and nums[j] % x == 0
vector<long long> g(mx+1);
for (int i = 1; i <= mx; i++) {
g[i] = cnt[i];
}
// g[x] = number of pair(i,j) (i < j) such that gcd(nums[i],nums[j]) == x
for (int i = mx; i >= 1; i--) {
for (int j = 2 * i; j <= mx; j += i) {
g[i] -= g[j];
}
}
// in-ex principle g[x] = (number of pair(i,j) (i<j) such that nums[i] % x == 0 and nums[j] % x == 0) - number of pair(i,j) (i < j) such that gcd(nums[i], nums[j]) == x * k (k >= 2)
// note: traverse from mx -> 1 to guarantee right result
// further reading: https://cp-algorithms.com/combinatorics/inclusion-exclusion.html
int q = queries.size();
vector<int> ans(q);
// remain part of the problem only need to sum up gcd count and query
vector<long long> pref(mx+1);
for (int i = 1; i <= mx; i++){
pref[i] = pref[i-1] + g[i];
}
for (int i = 0; i < q; i++){
long long id = queries[i] + 1;
int j = lower_bound(pref.begin(), pref.end(), id) - pref.begin();
ans[i] = j;
}
return ans;
}
};
/*
*/
Tính ra nếu biết cách đi từ max về 1 để tính count của gcd thì xong bài 4 rồi, mà tricky quá nhìn ko ra, mới nghĩ tới cái thằng largest mà ngu quácũng đúng nhưng hơi thiếu, nsqrt(n) đếm số lượng thằng có nghiệm là x (mọi x<=max(array))
sau đó duyệt ngược từ max(array) về 1. với mỗi số i đang xét thì lại duyệt toàn bộ nghiệm của nó, để trừ đi số pair nó tạo ra.
sort cái queries lại rồi 2 con trỏ là xong.

Đây bác ơi, Q3 thì nếu có 1 đỉnh chỉ có 1 đỉnh kề -> bảng sẽ có 1 hàng thôi bác. Còn không chắc chắn sẽ có 4 đỉnh có 2 đỉnh kề. Mình chọn ngẫu nhiên 1 đỉnh này và dựng hàng đầu tiên. Như TC 3 là lấy đỉnh 8 -> 6 -> 3. Ô đầu của hàng 2 sẽ là đỉnh kề còn lại của ô đầu hàng 1, là đỉnh 7, có hàng tiếp: 7->4->2. Giải tay thì nhanh mà em implement mất 1h ấy.xin ý tưởng q3 bác ơi, mấy cái constructive này khó chịu quá
Đề câu 2 hơi rối rắm, ngồi đọc một lúc mới hiểu.Mình 2 câu còn ăn bugs nữa chứ, nay code ngáo thật. Q2 cứ ngồi đần ra![]()
Ồ đoạn này là On^2 mà nhỉ, à nhầm += i ko phải += 1for (int i = 1; i <= mx; i++) { for (int j = i; j <= mx; j+=i){ cnt += f[j]; } }
T cũng ăn 1 big câu 2, quên đọc dòng "If it is not possible to remove all the suspicious methods, none should be removed."Mình 2 câu còn ăn bugs nữa chứ, nay code ngáo thật. Q2 cứ ngồi đần ra![]()

+=i mà bác nên k N^2 đâuỒ đoạn này là On^2 mà nhỉ
Đoạn đấy độ phức tạp là O(mx * ln(mx)).Ồ đoạn này là On^2 mà nhỉ, à nhầm += i ko phải += 1
Ừ do mình đọc đoạn đấy không kĩ, intuition chỗ này đếm khó quáĐoạn đấy độ phức tạp là O(mx * ln(mx)).
đúng rồiĐoạn đấy độ phức tạp là O(mx * ln(mx)).
cái đó là tổng của chuỗi điều hòa
vector<int> rg[SZ],g[SZ];
set<int> suspicious;
void dfs(int u) {
if(suspicious.count(u)) return;
suspicious.insert(u);
for(int v : rg[u]) {
dfs(v);
}
}
class Solution {
public:
vector<int> remainingMethods(int n, int k, vector<vector<int>>& invocations) {
for(int i=0;i<n;++i) {
rg[i].clear();
g[i].clear();
}
suspicious.clear();
for(auto &v : invocations) {
rg[v[0]].pb(v[1]);
g[v[1]].pb(v[0]);
}
dfs(k);
for(auto &v : invocations) {
int a=v[0],b=v[1];
if(!suspicious.count(a)&&suspicious.count(b)) {
suspicious.clear();
}
}
vector<int> res;
for(int i=0;i<n;++i) {
if(!suspicious.count(i)) {
res.pb(i);
}
}
return res;
}
};
class Solution {
public List<Integer> remainingMethods(int n, int k, int[][] invocations) {
Map<Integer, List<Integer>> invoke = new HashMap();
Map<Integer, List<Integer>> invoked = new HashMap();
Set<Integer> removeGroup = new HashSet();
for(int[] invocation:invocations){
int a = invocation[0];
int b = invocation[1];
invoke.computeIfAbsent(a, ArrayList::new);
invoked.computeIfAbsent(b, ArrayList::new);
invoke.get(a).add(b);
invoked.get(b).add(a);
}
helper(invoke, k, removeGroup);
List<Integer> res = new ArrayList();
for(int i =0 ;i<n;i++){
res.add(i);
}
for(Integer b:removeGroup){
if(!invoked.containsKey(b)){
continue;
}
for(int a:invoked.get(b)){
if(!removeGroup.contains(a)) return res;
}
}
for(Integer b:removeGroup){
res.remove(b);
}
return res;
}
public void helper(Map<Integer, List<Integer>> invoke, int k,Set<Integer> removeGroup){
if(removeGroup.contains(k)) return;
removeGroup.add(k);
if(!invoke.containsKey(k)) return;
for(Integer b:invoke.get(k)){
helper(invoke, b,removeGroup);
}
}
}
Bác cứ giải Q3 trong 30-40p thì sẽ cộng tầm 50-60đ/contest ấy, tầm tháng là lên nếu ko bị hụt hơi.target 1900 thì rank contest thường cỡ bao nhiêu thì lên dần được vậy các bác