HDU 5528 Count a * b(线性筛+积性函数)

B


00

xn
f[xn+1]=xf[xn]+m
m
n109
100W


代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX           1000005
#define   MAXN          1000005
#define   maxnode       105
#define   sigma_size    30
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   lrt           rt<<1
#define   rrt           rt<<1|1
#define   middle        int m=(r+l)>>1
#define   LL            long long
#define   ull           unsigned long long
#define   mem(x,v)      memset(x,v,sizeof(x))
#define   lowbit(x)     (x&-x)
#define   pii           pair
#define   bits(a)       __builtin_popcount(a)
#define   mk            make_pair
#define   limit         10000

//const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const LL     INFF  = 0x3f3f;
const double pi    = acos(-1.0);
const double inf   = 1e18;
const double eps   = 1e-8;
const LL     mod   = 1e9+7;
const ull    mx    = 133333331;

/*****************************************************/
inline void RI(int &x) {
      char c;
      while((c=getchar())<'0' || c>'9');
      x=c-'0';
      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
 }
/*****************************************************/

bool prime[MAX];
int pr[MAX];
int num[MAX];
ull f[MAX];
int tot;

void init(){
    mem(prime,0);tot=0;
    f[1]=1;
    for(int i=2;iif(!prime[i]){
            pr[tot++]=i;
            f[i]=2*i-1;
            num[i]=i;
        }
        for(int j=0;j1;
            if(i%pr[j]==0){
                if(i==num[i]){
                    num[i*pr[j]]=num[i]*pr[j];
                    f[i*pr[j]]=f[i]*pr[j]+(ull)(pr[j]-1)*i;
                }
                else{
                    f[i*pr[j]]=f[i/num[i]]*f[pr[j]*num[i]];
                    num[i*pr[j]]=num[i]*pr[j];
                }
                break;
            }
            else{
                num[i*pr[j]]=pr[j];
                f[i*pr[j]]=f[i]*f[pr[j]];
            }
        }
    }    
}

vector v;
int divi[MAX];
int xx;
void dfs(int x,int y){
    if(x==v.size()){
        divi[xx++]=y;
        return;
    }
    for(int i=0;i<=v[x].second;i++){
        dfs(x+1,y);
        y*=v[x].first;
    }
}

ull dfs(int x){
    if(xreturn f[x];
    int k=x;
    for(int i=0;iif(k%pr[i]==0){
            int ret=1;
            while(k%pr[i]==0){
                k/=pr[i];
                ret*=pr[i];
            }
            if(k==1){
                return dfs(x/pr[i])*pr[i]+(ull)(pr[i]-1)*(x/pr[i]);
            }
            else return dfs(k)*dfs(x/k);
            break;
        }
    }
    if(k!=1) return 2*k-1;
}
int main(){
    init();
    int t;
    cin>>t;
    while(t--){
        int n;
        scanf("%d",&n);
        int x=n;
        v.clear();
        for(int i=0;iif(x%pr[i]==0){
                int j=0;
                while(x%pr[i]==0){
                    x/=pr[i];
                    j++;
                }
                v.push_back(mk(pr[i],j));
            }
        }
        if(x!=1) v.push_back(mk(x,1));
        xx=0;
        dfs(0,1);
        ull ans=0;
        for(int i=0;i//cout<
        }
        printf("%I64u\n",ans);
    }
    return 0;
}

你可能感兴趣的:(HDU 5528 Count a * b(线性筛+积性函数))