hdu5608 几类经典的根号复杂度算法

I, as a ACMer, always take algorithm complexity into consideration when programming. Today, I introduce you some elegant algorithms of root Complex.

转载请注明Reproduced please specifydna049.com

1. s(n)=ni=1ni

Since The range of ni contains at most 2n . There may exist a algorithm of complexity O(n) .

LL getsum(LL n){ // The code is simple and easy to understand
    LL sum = 0;
    for(LL i=1,j;i<=n;i=j+1){ 
        j = n/(n/i);
        sum += (j-i+1)*(n/i);
    }
    return sum;
}

Actually, s(n) donate the number of positive integer point under graph xy=1 .

2. σk(n)=d|ndk

  1. σ0(n) donate the number of divisors.
  2. σ1(n) donate the sum of divisors.
LL mypow(LL x,LL n){
    LL r = 1;
    while(n){
        if(n&1) r=r*x;
        n>>=1;  x=x*x;
    }
    return r;
}
LL getr(LL n,LL k){
    LL r = 0,d;
    for(d=1;d*dif(n%d==0)  r += mypow(d,k) + mypow(n/d,k);
    }
    if(d*d == n) r+=mypow(d,k);
    return r;
}

The code above is primary and trival.

3. f(n)=ni=1σk(i)

f(n)=i=1nσk(n)=i=1nd|idk=d=1dkin[d|i]=d=1ndknd

If we get ts[n]=ni=1ik , similar to problem 1, we have fllowing C++ code:

LL getf(LL n){
    LL sum = 0;
    for(LL i=1,j;i<=n;i=j+1){ 
        j = n/(n/i);
        sum += (ts[j]-ts[i-1])*(n/i);
    }
    return sum;
}

Actuall, we have

ts[n]=n(n+1)2n(n+1)(2n+1)6n2(n+1)24k=1k=2k=3

and for general

i=1nip=k=1pj=0k1(1)jCjk(kj)p+1Ck+1n+1

4. g(n)=ni=1ϕ(i)

Throughout this blog, ϕ(n) donate the Euler function unless explicitly stated. ϕ(n) counts the positive integers less than or equal to n that are relatively prime to n. Euler’s product formula:

ϕ(n)=np|n(11p)

where the product is over the distinct prime numbers dividing n.

Now, we begin to computer g(n)

g(n)=i=1nϕ(i)=1xyn,gcd(x,y)=11

we define

gk(n)=i=1nϕ(i)=1xyn,gcd(x,y)=k1=f(nk)

and

i=1ngk(i)=1xyn1=n(n+1)2
So we have

g(n)=n(n+1)2k=2nf(nk)

Similar to problem 1,we have,

const int N=1000006;
LL ans[N];
void init(){
    memset(ans,-1,sizeof(ans));
    ans[1]=1;ans[2]=2;
}
LL getans(int n){
    if(n1) return ans[n];
    LL r = n*(n+1)/2;
    for(int i=2,j;i<=n;i=j+1){
        j = n/(n/i);
        r -= (j-i+1)*getans(n/i);
    }
    if(nreturn r;
}

5. Problem hdu5608

If

n23n+2=d|nf(d)

calculate
h(n)=i=1nf(i)mod109+7

Since

i=1nd|if(d)=i=1nf(i)ni=i=1nh(ni)

and we have,

i=1nd|if(d)=i=1nn23n+2=i=1n(n1)(n2)=n(n1)(n2)3

by conditon. Hence,
h(n)=n(n1)(n2)3i=2nh(ni)

//#pragma comment(linker,"/STACK:10240000,10240000")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair PLL;
#define clr(a,b) memset(a,b,sizeof(a))
#define MP make_pair
#define PB push_back
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l,m,lrt
#define rson m+1,r,rrt
/*------------------------- template ------------------------------*/
const int N=1000006;
const int M = 1e9+7;
const int inv3 = (M+1)/3;
int ans[N];
map<int,int> mp;
void init(){
    for(int i=0;i1)*(i-2)%M;
    }
    for(int i=1;i// Pretreatment acceleration
        for(int j=i<<1;jif(ans[j] < 0) ans[j] += M;
        }
    }
    for(int i=2;i1];
        if(ans[i] > M)  ans[i] -= M;
    }
}
int getans(int n){ 
    if(nreturn ans[n];
    map<int,int>::iterator it = mp.find(n); //Memory search
    if (it != mp.end())  return it->second;
    int r = LL(n)*(n-1)%M*(n-2)%M*inv3%M;
    for(int i=2,j;i<=n;i=j+1){
        j = n/(n/i);
        r -= LL(j-i+1)*getans(n/i)%M;
        if(r<0) r+=M;
    }
    mp.insert(pair<int,int>(n,r));
    return r;
}

int main(){
//    freopen("/Users/c10110057/Desktop/AC/in","r",stdin);
    init();
    int T,n;
    cin>>T;
    while(T--){
        scanf("%d",&n);
        cout<return 0;
}

6. Note

All C++ code above should be changed to fit different demands.Thanks Zimpha who provides some problems and ideas two years old.

你可能感兴趣的:(math)