码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 2749] 外星人

时间:2017-08-04 17:14:48      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:const   turn   ons   实现   ret   如何   奇数   cst   time   

题意

  给定 $n = \prod_{k = 1} ^ m {p_k} ^ {q_k}$ .

  求最小的 x , 使得 $\phi^x(n) = 1$ .

 

  $1 \le p_k \le {10} ^ 5$ .

  $1 \le q_k \le {10} ^ 9$ .

 

分析

  设 $$R(n) = \min_{\phi^x(n) = 1} x$$ .

 

  我们观察 n 是如何通过 $\phi$ 变成 1 的.

  即观察 $\phi(n)$ 的性质.

 

  发现1:

    当 $n = 2$ 时, $\phi(n) = 1$ .

    当 $n > 2$ 时, $\phi(n)$ 为偶数.

 

  发现2:

    当 n 为偶数时, $\phi(n) \le \frac{n}{2}$ .

    因为有质因数 2 , 而在 $\phi$ 的作用下, 2 会变成 1 , 所以至少少了一个 2 .

  

  我们发现, 在 phi 的作用下, 奇数会变成偶数, 偶数每次会缩小一倍, 最后由 2 变成 1 .

  $R(n) = O(\log n)$ .

  

  我们需要更精确的结果.

  设 $f(n)$ 表示 n 通过 $\phi$ 产生 2 的能力, 设 $n = 2 ^ k \times q$ .

    $$f(n) = \left\{ \begin{aligned} & f(q) + k & , k = 0 \\ & f(\phi(n)) & , k > 0 \end{aligned} \right.$$ .

  那么 $R(n) = f(n) + [ n 为奇数]$ .

 

  观察 $f$ 的性质.

  $f(p \times q) = f(p) + f(q)$ .

  $f(p ^ k) = kf(p)$ .

  所以 $f(\sum_{k = 0} ^ m {p_k} ^ {q_k}) = \sum_{k = 0} ^ m q_kf(p_k)$ .

 

  求 f(1), f(2), ..., f(100000) 通过线性筛来实现.

  或者也可以直接用定义.

 

实现

#include <cstdio>
#include <cctype>
  
#define F(i,a,b) for (int i=(a);i<=(b);i++)
  
#define LL long long
  
const int N=100000;
  
int v[N+5];
int pri[N+5],tot;
LL prod[N+5];
  
inline int rd(void) {
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c==-) f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-0;
    return x*f;
}
  
int main(void) {
    #ifndef ONLINE_JUDGE
        freopen("sdchr.in","r",stdin);
        freopen("sdchr.out","w",stdout);
    #endif
      
    v[1]=1; prod[1]=1;
    F(i,2,N) {
        if (!v[i]) {
            pri[++tot]=i;
            prod[i]=prod[i-1];
        }
        F(j,1,tot) {
            if (i*pri[j]>N) break;
            v[i*pri[j]]=1;
            prod[i*pri[j]]=prod[i]+prod[pri[j]];
            if (i%pri[j]==0) break;
        }
    }
      
    int nT=rd();
    F(c,1,nT) {
        int n=rd(); LL ans=0; int odd=1;
        F(i,1,n) {
            int p=rd(),q=rd();
            ans+=1LL*prod[p]*q;
            if (p==2) odd=0;
        }
        ans+=odd;
        printf("%lld\n",ans);
    }
     
    return 0;
}

 

[BZOJ 2749] 外星人

标签:const   turn   ons   实现   ret   如何   奇数   cst   time   

原文地址:http://www.cnblogs.com/Sdchr/p/7286084.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!