1. 程式人生 > >數論的一些黑科技

數論的一些黑科技

數論 problem ostream pro 暴力 width click https namespace

在【喬明達的省選專題】裏面有很多這樣的解題技巧:

把Σ*Σ類型的題O(n^2)轉化∑[n/i]∑[m/i],除法下結果相同的部分合並,復雜度降低至O(√n+√m)。當然論文裏的題型應該說說很經典了。這裏再積累幾個基礎題型。

1,求前n個正整數的約數之和,即=σ(i) ,(i=1到n)。其中n10^12

技術分享圖片

把除法下結果相同的部分合並,前面累加和用等差公式求和,復雜度為O(√n) 。

通俗理解公式: for(i=1;i<=n;i++) ans=ans+有因子i的數的個數=ans+n / i; (其中n/i=|i*1|+|i*2|+...+|i*(n/i)|,表示i是多少個數的因子)

例題: A New Function 。代碼:

技術分享圖片
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll solve(int n)
{
    ll ans=0;
    int B=sqrt(n);
    for(int i=2;i<=B;i++){
        ans
+=(ll)(n/i-1)*i; //前面根號n個直接暴力,由於不要1和本身,所以這裏減一。 if(n/i>=B+1){ //後面合並商相同部分 ,L,R代表的是範圍(個數)。 ll L=B+1,R=n/i; ans+=(L+R)*(R-L+1)/2; } } return ans; } int main() { int T,n,Case=0; scanf("%d",&T); while(T--){ scanf("%d",&n); printf(
"Case %d: %lld\n",++Case,solve(n)); } return 0; }
View Code

2,求前n個正整數的莫比烏斯函數之和,即=u(i),其中n10^11

技術分享圖片

通俗理解公式:for(i=1;i<=n;i++) sum=sum+(u(1)+u(2)+u(3)+...u(j)) (其中,i*j<=n,表示以1到j為因子,i相同的合並)。

3,

數論的一些黑科技