演算法練習記錄(24.10.5)

Oaths發表於2024-10-05

1.B. Brightness Begins

思路

要求最後的燈泡開啟的數量,由於一開始燈泡是開啟的,如果最後還需要開啟,那麼運算元量一定是偶數,移目至操作前提,需要燈泡的序號能整除 \(x\),由於遍歷1~x,推出最後燈泡 \(i\) 亮的條件是:\(1~i\) 中有偶數個\(i\)的因數,即 \(i\) 有偶數個因數,反之即有奇數個因數,由於因數成對存在,只有當這個數是完全平方數的時候才會有奇數個因數,所以題目轉化為: \(n\) 以內至少有 \(k\) 個非完全平方數。
正難則反,我們只需反求:\(n\) 以內至少有 \(n-k\) 個非完全平方數。第 \(n-k\) 個非完全平方數即 \((n-k)^2\) ,可得方程:\(n<=(n-k)^2\) ,變形得:
\(f(n)=n-\sqrt{n}>=k\),
由於 \(f(n)\) 單調遞增,所以問題變成了:找到最小的 \(n\) ,使得 \(f(n)>=k\) 成立,二分即可;
注意:使用sqrtl代替sqrt,精度需求高;

AC程式碼

    #include<bits/stdc++.h>
    #define endl '\n'
    #define ll long long
    #define pb push_back
    #define bs bitset
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    ll k;

    void solve(){
        cin>>k;
        ll l=1;ll r=2e18;
        while(l<r){
            ll mid=(l+r)>>1;
            if(mid-(int)sqrtl(mid)>=k)r=mid;
            else l=mid+1;
            //cout<<l<<" "<<r<<" "<<mid<<" "<<mid-sqrt(mid)<<endl;
        }
        cout<<l<<endl;
    }

    int main()
    {
        fast();
        
        int t=1;
        cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

相關文章