zoukankan      html  css  js  c++  java
  • [ICPC2020上海C] Sum of Log

    [ICPC2020上海C] Sum of Log

    Description

    给定 (x,y le 10^9)(sum_{i=0}^x sum_{j=[i=0]}^y [i & j=0][log_2(i+j)+1])

    Solution

    显然带 (log) 的那一项相当于是 (i,j) 的最大值的最高位,因此我们暴力枚举最高位是第几位,由谁贡献,后面的部分简单数位 dp 即可

    考场上的代码,写得比较丑

    (第一次正儿八经在考场上写出数位dp,魔咒算是破了)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 65;
    
    const int mod = 1e+9+7;
    
    int a[N], b[N], f[N][2][2];
    
    int solve(int pos, int limi, int limj)
    {
        if (pos == 0)
        {
            return 1;
        }
        if (~f[pos][limi][limj])
        {
            return f[pos][limi][limj];
        }
        int res = 0;
        if (limi == 0 || a[pos] == 1)
        {
            res += solve(pos - 1, limi, limj && b[pos] == 0);
        }
        if (limj == 0 || b[pos] == 1)
        {
            res += solve(pos - 1, limi && a[pos] == 0, limj);
        }
        res += solve(pos - 1, limi && a[pos] == 0, limj && b[pos] == 0);
    
        res %= mod;
    
        if (f[pos][limi][limj])
        {
            f[pos][limi][limj] = res;
        }
    
        return res;
    }
    
    int solve(int x, int y)
    {
        memset(a, 0, sizeof a);
        memset(b, 0, sizeof b);
    
        for (int i = 0; i < N; i++)
        {
            f[i][0][1] = f[i][1][0] = f[i][1][1] = -1;
        }
    
        int n = 0, m = 0;
        while (x)
        {
            a[++n] = x % 2;
            x /= 2;
        }
        while (y)
        {
            b[++m] = y % 2;
            y /= 2;
        }
    
        int presumi = 0, presumj = 0;
    
        for (int i = m; i > n; i--)
            presumj += b[i];
    
        int ans = 0;
    
        for (int high = n; high >= 1; high--)
        {
            presumi += a[high];
            presumj += b[high];
            if (presumi >= 1)
            {
                // cout << "[";
                ans += solve(high - 1, presumi == 1 && a[high] == 1, presumj == 0) * high;
                ans %= mod;
    
                // cout << "]";
            }
        }
    
        return ans;
    }
    
    void solve()
    {
        int x, y;
        scanf("%lld%lld", &x, &y);
        int ans = 0;
        ans += solve(x, y);
        ans += solve(y, x);
        printf("%lld
    ", ans % mod);
    }
    
    signed main()
    {
    
    
        ios::sync_with_stdio(false);
    
        memset(f, -1, sizeof f);
        int t;
        scanf("%lld", &t);
        while (t--)
        {
            solve();
        }
    
    }
    
  • 相关阅读:
    TCP Three-Way handshake
    java 连接mysql 和sql server2008代码
    关于dispatch_sync死锁问题
    MacBook Pro使用初体验之Mac快捷键汇总(持续更新中)
    Java对象的内存布局
    Android之adb
    ADT开发中的一些优化设置:代码背景色、代码字体大小、代码自动补全
    实用的eclipse adt 快捷键
    python操作Excel读--使用xlrd
    解决ImportError: cannot import name HTTPConnection的方法
  • 原文地址:https://www.cnblogs.com/mollnn/p/14130080.html
Copyright © 2011-2022 走看看