题解 | #E. 重生之我是QQ邮箱#

重生之我是QQ邮箱

https://ac.nowcoder.com/acm/contest/66877/E


E. 重生之我是QQ邮箱

因为只算最末尾的7个字符串,且只有6个按钮

第一按对的概率为1/6

总概率为 p = (1/6)^7

那期望为 E = n / p = n * 6^7

这题 长途大佬 出的很贼, 引入了很多干扰项

包括且不限于

小数四舍五入取整

如果无穷大,则返回 -1

根据题意,最终的结尾为

E^(2^m)

因为只取个位数,而个位数不受其他位数影响, 因此可以期望E提前 mod 10

((E % 10) ^ (2^m)) % 10

这个形态就是 欧拉降幂

alt

根据扩展欧拉定律

这边的p=10,其欧拉函数值10*(5-1)/5*(2-1)/2=4

而 b = 2^m

然后分类讨论即可

  1. m=0,1

  2. m>=2

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(new BufferedInputStream(System.in));

        int n = sc.nextInt();
        int m = sc.nextInt();

        if (n <= 6) {
            System.out.println(-1);
        } else {
            int e = n % 10;
            for (int i = 0; i < 7; i++) {
                e = e * 6 % 10;
            }

            long r = Euler.euler(e, 2, m, 10);
            System.out.println(r);
        }
    }

    static class Euler {

        static long gcd(long a, long b) {
            return b == 0 ? a : gcd(b, a % b);
        }

        static long euler(long a, long b, long c, long p) {
            long fp = phi(p);
            long g = gcd(a, p);
            if (g == 1) {
                return ksm(a, ksm(b, c, fp), p);
            } else {
                double e = (Math.log(fp) / Math.log(b));
                if (c < e) {
                    return ksm(a, (long)Math.pow(b, c), p);
                } else {
                    return ksm(a, ksm(b, c, fp) + fp, p);
                }
            }
        }

        static long euler(long a, long b, long p) {
            long fp = phi(p);
            long g = gcd(a, p);
            if (g == 1) {
                return ksm(a, b % fp, p);
            } else {
                if (b < fp) {
                    return ksm(a, b, p);
                } else {
                    return ksm(a, b % fp + fp, p);
                }
            }
        }

        static long phi(long n) {
            long r = n;
            for (int i = 2; i <= n / i; ++i) {
                if (n % i == 0) {
                    r = r / i * (i - 1);
                    while (n % i == 0) {
                        n /= i;
                    }
                }
            }
            if (n > 1) {
                r = r / n * (n - 1);
            }
            return r;
        }

        static long ksm(long b, long v, long mod) {
            long r = 1;
            while (v > 0) {
                if (v % 2 == 1) {
                    r = r * b % mod;
                }
                b = b * b % mod;
                v /= 2;
            }
            return r;
        }

    }

}
全部评论
其实不需要欧拉降幂,因为一个数的平方的末尾数字是有规律的,比如1结尾的无论平方多少次末尾都是1,2结尾的会经历2->4->6->6->6这样下去; 基本上三步就能走到一个循环出现的数字了
2 回复 分享
发布于 2023-10-21 18:11 浙江

相关推荐

6 2 评论
分享
牛客网
牛客企业服务