• 【积累】【数学】关于log运算


    有关log运算的二三题

    1,hdu Leftmost Digit

    题意:

    给定正整数 (n) ,输出 (n^n) 的最高位上的数字。其中, (1leq nleq1,000,000,000)

    解:

    [egin{align*} n^n&=a.b imes10^k\ lg(n^n)&=lg(a.b imes10^k)\&=lg(a.b)+k\ lg(n^n)-k&=lg(a.b)\ a&=(int)10^{lg(n^n)-k} end{align*} ]

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            printf("%d
    ",(int)pow(10,log10(n)*n-(ll)(log10(n)*n)));
        }
    }
    

    2,P1045 麦森数

    题意:

    对于给定整数 (P) ( (1000< P< 3100000) ) ,第一行输出十进制 (2^P-1) 的位数,第二行,输出十进制 (2^P-1) 的最后500位数字(每行输出50位,共输出10行,不足500位时高位补0)。

    解:

    对于输出位数:

    首先要知道 (2^P-1)(2^P) 的对应十进制数的位数是相同的(因为 (2^P) 尾数不为 (0) )。

    其次,对于一个数 (10^n) ,它的位数是 (n+1)

    那么对于 (k=2^P) 有:

    [egin{align*} k&=2^P\&=(10^{log_{10}\,2})^P\&=10^{P\,log_{10}\,2} end{align*} ]

    所以,(2^P-1) 的十进制位数等于 (2^P) 的十进制位数,等于 (P\,log_{10}2+1)

    输出最后500位:高精或者java

    代码:

    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main{
    	static final int maxn=100005;
    	static final BigInteger BI=null;
    	static Scanner input=new Scanner(System.in);
    	public static void main(String sssss[]) {
    		int p=input.nextInt();
    		BigInteger res=BI.valueOf(1);
    		BigInteger mod=BI.valueOf(10);
            BigInteger x=mod.pow(50),y;
    		int len=(int) (Math.log10(2)*p+1);
    		mod=mod.pow(500);
    		for(int i=1,j=0;i<=p;i++,j++) {
    			res=res.multiply(BI.valueOf(2));
    			if(j>5000){
                    res=res.mod(mod);j=0;
                }
    		}
            res=res.mod(mod);
    		res=res.subtract(BI.ONE);
    		System.out.println(len);
            for(int i=1;i<=10;i++){
                mod=mod.divide(x);
                y=res.divide(mod);
    		    System.out.println(String.format("%050d", y));
                res=res.subtract(y.multiply(mod));
            }
    	}
    }
    

    3,How Many Times?

    题意:

    初始有 (n) 个堆,第 (i) 堆有一个数 (i)

    (3) 种操作:

    • 1 X Y :把包含数 (X) 和包含数 (Y) 的堆合并
    • 2 X :如果包含数 (X) 的堆存在,删除该堆里最大的那个数
    • 3 X Y :输出 (frac{max(S_x,S_y)}{min(S_x,S_y)}) ,其中 (S_x=1 imes a_1 imes a_2 imesdots imes a_{size_x})(a_i) 是堆 (X) 的第 (i) 个数。

    且,如果输出的数大于 (10,000,000,000,000,000) ,则输出 (10,000,000,000,000,000)

    输出数据与标准数据的差不能超过 (10^{-6})

    解:

    启发式合并。

    对于高精度的运算,用浮点数的对数加法运算代替。

    [frac{a_1 imes a_2 imesdots imes a_{size_x}}{b_1 imes b_2 imesdots imes b_{size_y}}=10^{lg frac{a_1 imes a_2 imesdots imes a_{size_x}}{b_1 imes b_2 imesdots imes b_{size_y}}} ]

    [egin{align*} \ lg frac{a_1 imes a_2 imesdots imes a_{size_x}}{b_1 imes b_2 imesdots imes b_{size_y}}&=lg(a_1 imes a_2 imesdots imes a_{size_x})-lg(b_1 imes b_2 imesdots imes b_{size_y})\&=(lg\,a_1+lg\,a_2+dots+lg\,a_{size_x})-(lg\,b_1+lg\,b_2+dots+lg\,b_{size_y}) end{align*} ]

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const double ep=1e-8;
    const int mod=998244353;
    const int inf=0x3f3f3f3f;
    const int maxn=1e5+5;
     
    priority_queue<int>que[maxn];
    double val[maxn];
    int fa[maxn];
    int main()
    {
        int n,m,op,x,y;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            que[i].push(i);
            fa[i]=i;
            val[i]=log10(i);
        }
        while(m--)
        {
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d",&x,&y);
                x=fa[x];
                y=fa[y];
                if(!x||!y||x==y)continue;
                if(que[x].size()<que[y].size())swap(x,y);
                val[x]+=val[y];val[y]=0;
                while(!que[y].empty()){
                    que[x].push(que[y].top());
                    fa[que[y].top()]=x;
                    que[y].pop();
                }
                que[y]=priority_queue<int>();
            }else if(op==2){
                scanf("%d",&x);
                x=fa[x];
                if(!x)continue;
                val[x]-=log10(que[x].top());
                fa[que[x].top()]=0;
                que[x].pop();
            }else{
                scanf("%d%d",&x,&y);
                x=fa[x];y=fa[y];
                printf("%.6f
    ",pow(10,min(fabs(val[x]-val[y]),16.0)));
            }
        }
    }
    
  • 相关阅读:
    IO(文件)处理
    集合 (set) 的增删改查及 copy()方法
    字典 (dict) 的增删改查及其他方法
    列表(List) 的增删改查及其他方法
    细数Python中的数据类型以及他们的方法
    CCNA基础 IP地址子网划分
    [转] SSH原理与运用(2):远程操作与端口转发
    记俩次连续失误操作造成的数据丢失损坏解决
    CentOS 下 MySQL DateBasic 抢救
    China Mobile 免流原理
  • 原文地址:https://www.cnblogs.com/kkkek/p/14105661.html
Copyright © 2020-2023  润新知