thảo luận [Học Tập] Topic thuật toán

  • Người tạo chủ đề Người tạo chủ đề unknowpc90
  • Ngày bắt đầu Ngày bắt đầu
bài này ý tưởng khởi nguồn của nó là mobius inverse function.
Nhưng k cần biết cái trên, chỉ cần biết (tổng phi(d) với d chạy trên tập ước của n = n)
Kết quả = phi(d) * số tập con thực sự mà mỗi phần tử trong đó đều chia hết cho d (với d chạy từ 1 đến max(a_i), thường giới hạn khoảng 10^5-10^6)
Phi d có thể precompute, số tập hợp thì là 2^(số phần tử chia hết cho d) - 1, cũng precompute nốt
Độ phức tạp là khoảng n*sqrt(n)
giờ mới biết cái mobius này
Rt7E8tX.png

Kết quả = phi(d) * số tập con thực sự mà mỗi phần tử trong đó đều chia hết cho d (với d chạy từ 1 đến max(a_i), thường giới hạn khoảng 10^5-10^6)
Phi(d) là hàm phi euler à thím? sao ra được cái này thế thím?
 
ờ, totient function đó.
thay gcd vô cái n bên trên, xong gộp những thằng d giống nhau vào
Test 1:

3 4 5

d = 1 -> 3 phần tử chia hết cho 1 -> (2 ^ 3 - 1) * phi(1) = 7
d = 2 -> (2 ^ 1 - 1) * phi(2) = 1
d = 3 -> (2 ^ 1 - 1) * phi(3) = 2
d = 4 -> (2 ^1 - 1) * phi(4) = 2
d = 5 -> (2^1 - 1) * phi(5) = 4

Cộng lại ko ra 119 như trong test. mình tính có sai ở đâu ko nhỉ?
 
bài này easy chứ medium gì. tôi từng cho làm lúc phỏng vấn.
đứa nào dùng for loop từ 1 -> n 1 phát là tôi "thank you for your time" rồi mời về ngay lập tức.

giải quyết problem về hàm pow thì tôi cần gì phải đi phỏng vấn ai lol.

vấn đề là muốn xem ứng viên họ kinh nghiệm thế nào về học thuật. Đi phỏng vấn ở mức lương từ 150-175K mà được hỏi về code hàm pow mà nghĩ người ta chỉ cần cái solution vòng lặp for từ 1-> n thì nên tự rút lui vì bạn đấy đã apply nhầm vị trí và level. tốt nhất là nên đi tìm việc ở mức 80K...
Ở trên thì nói là từng cho làm lúc phỏng vấn. Dưới lại nói cần gì đi pv ai cái đó. Sao câu dưới lại đá câu trên vậy?
 
Test 1:

3 4 5

d = 1 -> 3 phần tử chia hết cho 1 -> (2 ^ 3 - 1) * phi(1) = 7
d = 2 -> (2 ^ 1 - 1) * phi(2) = 1
d = 3 -> (2 ^ 1 - 1) * phi(3) = 2
d = 4 -> (2 ^1 - 1) * phi(4) = 2
d = 5 -> (2^1 - 1) * phi(5) = 4

Cộng lại ko ra 119 như trong test. mình tính có sai ở đâu ko nhỉ?
đọc nhầm bội chung nhỏ nhất (lcm) thành ước chung lớn nhất (gcd) :D :D
thấy trên stackoverflow có solution bằng dp 8-)8-) giới hạn i như bài này
https://stackoverflow.com/questions...ommon-multiples-of-all-subsets-of-a-given-set
 
Giờ xem lại nguồn mới thấy bài này thuộc dạng siêu khó các bác à. Nó là bài F trong ICPC Regional Hatyai 2012, được upload trên gym của Codeforces https://codeforces.com/gym/101549/standings. Trong bảng rank này chỉ có mỗi team của tourist làm được, team rank 2 cũng là team vô địch WF mà còn không giải được :surrender:
Vkl thế mà mấy bác nhà mình giải 1 nốt nhạc. Vozer lương chuẩn 350m là có thật :sweat: :sweat:
 
Nay thấy topic này vắng quá. Nên mình sẽ share bài mình mới làm chiều nay.
https://leetcode.com/problems/powx-n/
Yêu cầu là implement hàm pow.
Đọc đề xong thấy bài này easy vkl, k hiểu sao lại là medium, nghĩ trong bụng bài này chắc done trong 1 nốt nhạc. Chỉ cần 1 vòng for chạy từ 0->n rồi nhân lại là xong. dpt là O(n) :D. Đến lúc submit thì bị timeout :beat_brick:.
Lúc đó ngồi nghĩ kỹ lại mới thấy bài này hoàn toàn có thể giải với đpt là O(logN) :p.
tại vì m^n = m^(n/2)*m^(n/2) như vậy mình chỉ cần tính m^(n/2) 1 lần thôi.
C++:
class Solution {
public:
    double myPow(double x, int n) {
        double result = 1;
        x = n > 0 ? x : 1/x;
        for (int i = 0; n != 0; i++){
            result *= n%2!=0 ? x : 1;
            n/=2;
            x = x*x;
        }
        return result;
    }
};
Bài này chắc là kinh điển, nên chắc nhiều anh em cũng từng làm qua rồi. :D
uả bài này nếu em giải bằng JS thì kq là: return x ** n
Mà bản chất x ** n là 1 vòng for hả bác
 
br1ysj7.png


Mấy bác cho em hỏi bài này với, ý tưởng của e là xét 4 ô xung quanh của ô đang xét (ô đang xét tất nhiên là giá trị =1, còn 4 ô xung quanh ô cần xét là [i-1][j],[i-1][j-1],[j-1],[i-1][j+1]), lấy max của 4 thằng đó + với 1, sau khi xét xong mảng, nếu ô đó có dp==1 thì ta tăng đáp số lên 1, nếu > 1 nghĩa là đã được đếm nên không tăng đáp án. Mà không hiểu sao cứ sai, em hiểu sai chỗ nào hay nó có test đặc biệt vậy:surrender:
C++:
#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        int a[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>a[i][j];
            }
       }
        vector<vector<int> >dp(n+2,vector<int>(m+2,0));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(a[i-1][j-1]==1){
    dp[i][j]=max(max(max(dp[i-1][j-1],dp[i-1][j]),dp[i-1][j+1]),dp[i][j-1])+1;
                }
            }
        }
        int res=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(dp[i][j]==1) res++;
            }
        }
        cout<<res<<"\n";
    }
  }
}
 
br1ysj7.png


Mấy bác cho em hỏi bài này với, ý tưởng của e là xét 4 ô xung quanh của ô đang xét (ô đang xét tất nhiên là giá trị =1, còn 4 ô xung quanh ô cần xét là [i-1][j],[i-1][j-1],[j-1],[i-1][j+1]), lấy max của 4 thằng đó + với 1, sau khi xét xong mảng, nếu ô đó có dp==1 thì ta tăng đáp số lên 1, nếu > 1 nghĩa là đã được đếm nên không tăng đáp án. Mà không hiểu sao cứ sai, em hiểu sai chỗ nào hay nó có test đặc biệt vậy:surrender:
C++:
#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        int a[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>a[i][j];
            }
       }
        vector<vector<int> >dp(n+2,vector<int>(m+2,0));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(a[i-1][j-1]==1){
    dp[i][j]=max(max(max(dp[i-1][j-1],dp[i-1][j]),dp[i-1][j+1]),dp[i][j-1])+1;
                }
            }
        }
        int res=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(dp[i][j]==1) res++;
            }
        }
        cout<<res<<"\n";
    }
  }
}
Cần kiểm tra 8 vị trí xung quanh chứ không phải 4.
Bác có thể thử lại test này. Kết quả là 1.

1
3 3
0 0 1
1 1 1
1 1 1
 

Thống kê chủ đề

Ngày tạo
unknowpc90,
Người trả lời cuối
Spaghetti Code,
Trả lời
1.460
Lượt xem
154.144
Quay lại
Lên đầu trang