• Gym 102900C. Sum of Log(ICPC2020上海C)数位dp


    题目链接
    思路
    因为前提条件(i)&(j==0),所以i和j的任意一位最高位一定不同,那么(log_2^{i+j})就相当于看i或者j最高位为1在第几位,然后计算贡献。
    转化为二进制考虑每一位的情况,数据范围只到1e9,考虑通过数位dp来得到所有方案数。如果没有两个位数不一样的其实可以当作默认把小的那个数前面补齐了前导0.
    (dp[i][1/0][1/0]:)在数字n,m的二进制表示下第i位,数字n在这一位是否取到上限的状态,数字m是否取到上限的状态的所有方案数。若有上限的限制就是1,没有上限的限制就是0。可以通过dfs写数位dp的写法来解决这个问题。
    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int mod = 1e9 + 7;
    
    const int N = 50;
    int dp[N][2][2];
    int a[N], b[N], n, m;
    
    LL dfs(int pos, bool x, bool y) {
        if(!pos) return 1;
        if(dp[pos][x][y] != -1) return dp[pos][x][y];
        int up1 = x ? a[pos] : 1;
        int up2 = y ? b[pos] : 1;
        LL sum = 0;
        for(int i = 0; i <= up1; i++) {
            for(int j = 0; j <= up2; j++) {
                if(!(i & j)) {
                    sum += dfs(pos - 1, x && i == a[pos], y && j == b[pos]);
                    sum %= mod;
                }
            }
        }
        return dp[pos][x][y] = sum;
    }
    
    void solve() {
        memset(a, 0, sizeof a);
        memset(b, 0, sizeof b);
        scanf("%d%d", &n, &m);
        int idx1 = 0, idx2 = 0;
        while(n) {
            a[++idx1] = n % 2;
            n /= 2;
        }
        while(m) {
            b[++idx2] = m % 2;
            m /= 2;
        }
        memset(dp, -1, sizeof dp);
        LL res = 0;
        for(int i = 1; i <= max(idx1, idx2); i++) {
            LL cnt = 0;
            if(i <= idx1) cnt += dfs(i - 1, idx1 == i, i - 1 >= idx2);
            if(i <= idx2) cnt += dfs(i - 1, i - 1 >= idx1, idx2 == i);
            res += 1LL * cnt * i % mod;
            res %= mod;
        }
        printf("%lld
    ", res);
    }
    
    int main() {
        // freopen("in.txt", "r", stdin);
        int t; cin >> t; while(t--)
        solve();
        return 0;
    }
    
  • 相关阅读:
    Spark SQL ---一般有用
    idea快捷键
    04.Scala编程实战 ---没看
    03.Scala高级特性 ---没看
    02.Actor编程 ---没看
    01.Scala编程基础 ---没看
    附6、Storm面试题目答疑 ---一般有用
    扩展运算符
    ES6新增数组方法(部分)
    for of 循环
  • 原文地址:https://www.cnblogs.com/ZX-GO/p/14412945.html
Copyright © 2020-2023  润新知