• Heretical … Möbius【18EC】


    Heretical … Möbius

    有一个序列

    [f = igg | mu(i) igg |, i = 1,2,3,...,1e9 ]

    给一个长度为 200 的子序列,该子序列在 (f) 中第一次出现的位置,若没有出现过,则输出 -1

    思路

    首先, (ig | mu(x) ig |)(x) 被某个数的平方整除的话则为 0 ,否则就是 1

    因为序列的长度只有 200 , 考虑 200 以内的质数平方序列 4,9,25,49,121,169

    可以暴力枚举起始位置对这六个数的模数

    虽然 (M = 4*9*25*49*121*169 = 901800900 ≈ 9e8)

    但是我们并不需要全部枚举出来,因为很多模数不合法。这里合法直接 (O(200)) 判断就好

    枚举完之后,用 (CRT) (中国剩余定理) 计算出初始位置 (x) , 注意此时的 (x) 未必合法,因为其余位置未必都是 1 , 所以还需要计算 ([x,x + 199])(200) 个数的 (ig |mu(i) ig |)

    ,注意还需要继续在 (1e9) 范围内继续枚举 (x + M)

    int mu(int v) {
        for (int i = 1; i <= cnt and prime[i] * prime[i] <= v; i++) {
            if (v % (prime[i] * prime[i]) == 0)return 0;
    
            if (v % prime[i] == 0)v /= prime[i];
            //我大意了啊,没有加这一行, TLE 了一个晚上 /wx
        }
        return 1;
    }
    

    这里 取模运算是一种很慢的运算, 而这个函数又是在 (dfs) 的低端调用,所以这个函数调用次数巨大。不加那一行会变得巨慢 ,真的长知识了

    还有一个地方就是计算的开始位置是 (x) 的话, 要判断 (x + 199) 是否在 (1e9) 范围内

    否则不合法

    还需要对 0 的数量做一个大概的合理估计,很显然可以估出一个下界 50 ,因为用 4 就可以筛出这么多,可以凭感觉估一个 100 ,其实可以稍微做一下计算

    L = [4,9,25,49,121,169]
    ans = 0
    for i in L:
        ans += 200 // i
    ans
    >>> 86
    
    /*
     * @Author: zhl
     * @LastEditTime: 2020-11-30 21:22:38
     */
    #include<bits/stdc++.h>
    #pragma GCC optimize(3)
    #define int long long
    using namespace std;
    
    void ex_gcd(int a, int b, int& gcd, int& x, int& y) {
        if (b == 0) {
            x = 1;
            y = 0;
            gcd = a;
        }
        else {
            ex_gcd(b, a % b, gcd, y, x);
            y -= x * (a / b);
        }
    }
    
    const int M = 901800900;
    const int m[] = { 0,4,9,25,49,121,169 };
    int a[10], ti[10];
    int CRT() {
        int res = 0;
        int x, y, gcd;
    
        for (int i = 1; i <= 6; i++) {
            int tmp = M / m[i];
            ex_gcd(tmp, m[i], gcd, x, y);
            x = (x % m[i] + m[i]) % m[i];
            ti[i] = x * tmp;
            res = (res + tmp * a[i] * x) % M;
        }
        return (res + M) % M;
    }
    
    char s[300];
    bool ok(int r, int mod) {
        int st = r == 0 ? 1 : 1 - r + mod;
        while (st <= 200) {
            if (s[st] != '0')return false;
            st += mod;
        }
        return true;
    }
    int ans;
    int prime[100010], cnt, vis[100010];
    void init() {
        for (int i = 2; i <= 100000; i++) {
            if (not vis[i])prime[++cnt] = i;
            for (int j = 1; j <= cnt and prime[j] * i <= 100000; j++) {
                vis[prime[j] * i] = 1;
                if (i % prime[j] == 0)break;
            }
        }
    }
    int mu(int v) {
        for (int i = 1; i <= cnt and prime[i] * prime[i] <= v; i++) {
            if (v % (prime[i] * prime[i]) == 0)return 0;
            if (v % prime[i] == 0)v /= prime[i];
        }
        return 1;
    }
    bool judge(int v) {
        for (int i = 1; i <= 200; i++) {
            if (mu(v + i - 1) != s[i] - '0')return false;
        }
        return true;
    }
    void dfs(int now) {
        if (now == 7) {
            /*for (int i = 1; i <= 6; i++) {
                cout << a[i] << endl;
            }*/
            int v = CRT();
            if (v == 0)v = M;
            while (v + 199 <= 1e9 and v < ans) {
                if (judge(v)) ans = v;
                v += M;
            }
            return;
        }
    
        for (int i = 0; i < m[now]; i++) {
            if (not ok(i, m[now]))continue;
            a[now] = i;
            dfs(now + 1);
        }
    }
    signed main() {
        init();
        for (int i = 1; i <= 10; i++) {
            scanf("%s", s + i * 20 - 20 + 1);
        }
        int ct = 0; for (int i = 1; i <= 200; i++)if (s[i] == '0')ct++;
        if (ct < 50 or ct > 100)puts("-1");
        else {
            //printf("%s
    ", s + 1);
            ans = 1e9;
            dfs(1);
            if (ans == 1e9)puts("-1");
            else printf("%lld
    ", ans);
        }
    }
    
  • 相关阅读:
    Linux:sudo,没有找到有效的 sudoers 资源。
    Python中关于CSV文件中的I/O
    Python数据处理进阶——pandas
    脚本的含义
    Common.Logging.dll----------配置方式,可选引用,用于日志输出
    Net作业调度
    MySQL版本介绍
    在 Windows 上安装Rabbit MQ 指南
    版本控制器
    C# 中的占位符本质
  • 原文地址:https://www.cnblogs.com/sduwh/p/14063734.html
Copyright © 2020-2023  润新知