• codeforces597 div2 F 数位dp


    codeforces597 div2 F 数位dp

    题意:

    求[L,R]中a&b==0的“对数”

    思路:

    一个典型的求“对数”的数位dp,对比普通的数位dp,共用一个pos,维护两个limit。剩下的就是“暴搜”了,当然注意去重,因为是求对数就不是简单的(ans_{R}-ans_{L-1})了。还有要注意lim的状态也要保存,不然会超时。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define X first
    #define Y second
    #define PB push_back
    #define LL long long
    #define pii pair<int,int>
    #define MEM(x,y) memset(x,y,sizeof(x))
    #define bug(x) cout<<"debug "#x" is "<<x<<endl;
    #define FIO ios::sync_with_stdio(false);
    #define ALL(x) x.begin(),x.end()
    #define LOG 20
    const int inf =1e9;
    const int maxn =3e5+7;
    const int mod = 1e9+7;
    LL dp[35][2][2];
    
    LL solve(int L,int R,int pos,int lim1,int lim2){
        if(pos<0) return 1;
        if(dp[pos][lim1][lim2]!=-1) return dp[pos][lim1][lim2];
        int up1=lim1?((L>>pos)&1):1,up2=lim2?((R>>pos)&1):1;
        dp[pos][lim1][lim2]=0;
        for(int i=0;i<=up1;i++)for(int j=0;j<=up2;j++)
            if((i&j)==0)
                dp[pos][lim1][lim2]+=solve(L,R,pos-1,lim1&&i==up1,lim2&&j==up2);
        return dp[pos][lim1][lim2];
    }
    
    LL do_solve(int l,int r){
        if(l<0||r<0) return 0;
        MEM(dp,-1);
        return solve(l,r,31,1,1);
    }
    
    int main(){
        FIO;
        int t,l,r;
        cin>>t;
        while(t--){
            MEM(dp,-1);
            cin>>l>>r;
            cout<<do_solve(r,r)-do_solve(l-1,r)*2+do_solve(l-1,l-1)<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    LRu Cache算法原理
    c# 哈希表
    c# 获取二维数组的行数和列数
    Linq
    DataTable使用
    Wpf学习
    数据库配置
    js 数字保留两位小树
    平面数据转换为树形结构
    mysql操作
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/11794925.html
Copyright © 2020-2023  润新知