zoukankan      html  css  js  c++  java
  • 【cf1245F】F. Daniel and Spring Cleaning(数位dp)

    传送门

    题意:
    给出(l,r),要求((a,b))的对数且满足:

    • (lleq a,bleq r)
    • (a+b=a xor b)

    思路:
    如果将问题转化为前缀问题我们在二进制上面就会比较好分析问题。
    (solve(l,r))(0leq aleq l,0leq bleq r)时满足条件的对数,那么我们根据容斥的思想即可知道答案为:

    [solve(r,r)-solve(l-1,r)-solve(r,l-1)+solve(l-1,l-1) ]

    那么我们现在只需要考虑求(solve(l,r))
    这里我们直接可以根据(pair)型的数位(dp)来求即可,注意到(a+b=a xor b)的条件为(a&b=0)
    所以我们直接从高到低枚举每一位数位(dp)计算答案即可。
    代码如下:

    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/8 16:01:12
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 31;
    
    ll dp[N][2][2];
    
    ll dfs(int l, int r, int k, int up1, int up2) {
        if(k == -1) return 1;
        if(dp[k][up1][up2] != -1) return dp[k][up1][up2];
        ll res = 0;
        int a = 1, b = 1;
        if(up1) a = (l >> k & 1);
        if(up2) b = (r >> k & 1);
        for(int i = 0; i <= a; i++) {
            for(int j = 0; j <= b; j++) {
                if(!(i & j)) {
                    res += dfs(l, r, k - 1, up1 & (i == a), up2 & (j == b));
                }
            }   
        }    
        return dp[k][up1][up2] = res;
    }
    
    ll solve(int l, int r) {
        if(l < 0 || r < 0) return 0;
        memset(dp, -1, sizeof(dp));
        ll res = dfs(l, r, 30, 1, 1);
        return res;
    }
    
    void run() {
        int l, r; cin >> l >> r;
        ll ans = solve(r, r) - solve(l - 1, r) - solve(r, l - 1) + solve(l - 1, l - 1);
        cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    
  • 相关阅读:
    C# 使用 sid 连接 Oracle(无需安装 Oracle 客户端)
    命令模式(Command Pattern)
    仅仅使用Google就完成了人生第一次破解
    GeoServer跨域问题
    List与DataTable相互转换
    GeoServer2.14.1修改端口
    坐标转换C#(Gcj02、wgs84、bd09互转)
    nginx启动报错(1113: No mapping for the Unicode character exists in the target multi-byte code page)
    C# 操作 Mongodb
    DocumentFormat.OpenXml导出word合并(文件被另一个进程占用)
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12451852.html
Copyright © 2011-2022 走看看