Hướng dẫn giải của Bedao Grand Contest 13 - SHOPPING


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Subtask ~1~: Giả sử một người có ~x~ đồng. Người đó sẽ chỉ sử dụng hết được số tiền đó khi họ mua đúng ~y~ con búp bê (hoặc lego) giá ~z~ đồng sao cho ~y * z = x~.

Vì vậy, ta sẽ dùng ~1~ vòng lặp từ ~1~ đến ~n-1~ để chia ~i~ đồng cho Alob, và ~n-i~ đồng cho Bice. Ta sẽ dùng thêm 1 vòng lặp từ ~1~ đến ~i~ để đếm số cách Alob mua được hết số tiền của mình, và một vòng lặp tương tự từ ~1~ đến ~n-i~ cho Bice.

Độ phức tạp ~O(n^3)~.

Subtask ~2~:

Dễ chứng minh để ~y * z = x~ thì ~y~ và ~z~ đều phải là ước của ~x~. Vì vậy ta có thể chuẩn bị trước kết quả cho mỗi giá trị ~x~ để loại bỏ ~2~ vòng lặp của Alob và Bice.

Gọi ~f[i]~ là số cách mua khi một người có ~i~ đồng, và ~f[i]~ là số ước của ~i~.

Đáp án: ~\sum\limits_{i = 0}^{n}(f[i] \times f[n-i])~.

Độ phức tạp ~O(n)~.

Code mẫu

#include <bits/stdc++.h>
#define ll long long
#define rep(i,m,n) for (ll i=m;i<=n;i++)
#define reb(i,m,n) for (ll i=m;i>=n;i--)
#define rv(i,vt) for (auto i:vt)
#define ii pair<ll,ll>
#define vi vector<ll>
#define F first
#define S second
#define pb push_back
#define sz(v) (ll)v.size()
#define iii tuple<ll,ll,ll>
using namespace std;
const ll N=1e6+5,mod=1e9+7;
ll f[N+5],n;
void elixprep(){
    rep(i,1,N)
    for (ll j=i;j<=N;j+=i) f[j]++;
}
void elix()
{
    cin>>n;
    ll res=0;
    rep(i,1,n-1) res+=f[i]*f[n-i];
    cout<<res;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll tests=1;
    //cin>>tests;
    elixprep();
    while (tests--){
        elix();
        cout<<endl;
}
    cerr << "\n" << (double)clock() / CLOCKS_PER_SEC * 1000 << " ms";
}
//listen to trap music. it won't help

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.