其他分享
首页 > 其他分享> > 题解luogu P1920 【成功密码】

题解luogu P1920 【成功密码】

作者:互联网

一道还行的数论题。

难点主要是在特判和快速幂上 首先介绍一下这个符号:\sum

\sum是一个求和符号,英语名称:Sigma,汉语名称:西格玛。 

\sum_{i=1}^{n}k 的意思是:其中 i 表示下界,n 表示上界,k 从 i 开始取数,一直取到 n,全部加起来。

所以本题就是求 \dfrac{x^1}{1}+\dfrac{x^2}{2}+\dfrac{x^3}{3}+...+\dfrac{x^n}{n}

 
那不就简单了吗,直接暴力。但是因为数据大,只能过 3 个点。

所以这里可以用快速幂:

int mi(int a,int b){
    int ans=1;
    while(b!=0){
        if(b&1) ans=ans*a;
        a=a*a;
        b=b>>1;
    }
    return ans;
}


 

还是只过了3个,其他 TLE。

单看这里的 k,是一个除法:

(这里假设 x 为 0.9999。)

- 当 i=1 时,原式 = \tfrac{0.9999^1}{1}=0.9999 

- 当 i=2 时,原式 =\tfrac{0.9999^2}{2}\approx 0.4999

- 当 i=100 时,原式 = \tfrac{0.9999^{100}}{100} \approx 0.0099

- 当 i=1000 时,原式 = \tfrac{0.9999^{1000}}{1000}\approx 9.048e-4


显而易见,i 越大,整体的值越小,又因为要精确到4位小数,所以当 n 足够大时,就可以将它变小(当 n>t 时就把 n 设为 t)。


AC代码:

#include<bits/stdc++.h>
using namespace std;
double sum=0;//别写成int
double mi(double a,long long b){
    double ans=1;
    while(b!=0){
        if(b&1) ans=ans*a;
        a=a*a;
        b=b>>1;
    }
    return ans;
}//快速幂,用递归的也可以。

int main(){
    double x;
    long long n;
    cin>>x>>n;
    if(n>80000) n=80000;//特判,这里80000左右都可以
    for(int i=1;i<=n;i++){
        sum+=mi(x,i)/i;
    }//累加
    printf("%.4lf",sum);

    return 0;
} 


 

标签:P1920,int,题解,ans,特判,long,double,luogu,80000
来源: https://blog.csdn.net/zlj8769/article/details/122270215