zoukankan      html  css  js  c++  java
  • Codeforces Round #450 (Div. 2)

    D. Unusual Sequences

    分析

    如果至少有一组解,则要 (y)(x) 整除,也就是说 (a_i) 一定是 (x) 的倍数,可设 (dp[i]) 为 和为 (i)(gcd = 1) 时的方案数,首先呢,如果不考虑 (gcd) 的限制,可以发现,(dp[i]=1<<(i-1)) ,那么我们只要减去那些 (gcd > 1) 的方案数,枚举因子就好了,记忆化搜索即可。

    code

    #include <bits/stdc++.h>
    using namespace std;
    const int MOD = 1e9 + 7;
    long long p2(int x) {
        long long a = 1, k = 2;
        while (x) {
            if (x & 1) a = a * k % MOD;
            k = k * k % MOD;
            x >>= 1;
        }
        return a;
    }
    map<int, long long> dp;
    long long dfs(int x) {
        if (dp.count(x)) return dp[x];
        long long res = p2(x - 1);
        for (int i = 1; i * i <= x; i++) {
            if (x % i == 0) {
                if (i != 1) {
                    res = (res - dfs(x / i) + MOD) % MOD;
                }
                if(i * i != x) res = (res - dfs(i) + MOD) % MOD;
            }
        }
        return dp[x] = res;
    }
    int main() {
        dp[1] = 1;
        int x, y, n;
        long long ans = 0;
        cin >> x >> y;
        if (y % x == 0) {
            ans = dfs(y / x);
        }
        cout << ans << endl;
        return 0;
    }
    

    E. Maximum Questions

    分析

    (dp[i]) 表示从 (i) 开始((s[i...n-1]))所能构成的不相交 (t) 串的最多个数,并维护最小花费 (mn[i])

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    string s;
    int dp[N], mn[N], ab[N];
    int main() {
        int n, m, k = 0;
        cin >> n >> s >> m;
        for (int i = n - 1; i >= 0; i--) {
            if(s[i] == '?') k++;
            if(s[i] == '?' || s[i] == 'a') {
                if(s[i + 1] == 'b' || s[i + 1] == '?') ab[i] = ab[i + 2] + 2;
                else ab[i] = 1;
            }
            if(n - i >= m) {
                dp[i] = dp[i + 1];
                mn[i] = mn[i + 1];
                if(ab[i] >= m) {
                    if(dp[i + m] + 1 > dp[i]) {
                        dp[i] = dp[i + m] + 1;
                        mn[i] = mn[i + m] + k;
                    } else if(dp[i + m] + 1 == dp[i]) {
                        mn[i] = min(mn[i], mn[i + m] + k);
                    }
                }
                if(s[i + m - 1] == '?') k--;
            }
        }
        cout << mn[0] << endl;
        return 0;
    }
    
  • 相关阅读:
    php-instanceof运算符
    windows10-seaslog安装笔记
    [类和对象]1 封装 调用成员函数
    [C++] 拓展属性
    [C++] 引用详解
    [C++] Const详解
    ROS 常用
    win10 ubuntu16双系统安装教程
    [0] OpenCV_Notes
    Ubuntu16.04安装openCV的问题集合
  • 原文地址:https://www.cnblogs.com/ftae/p/8325956.html
Copyright © 2011-2022 走看看