Codeforces 1245F. Daniel and Spring Cleaning(容斥原理+数位DP)

Posted BakaC1rno

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1245F. Daniel and Spring Cleaning(容斥原理+数位DP)相关的知识,希望对你有一定的参考价值。

传送门

题目大意

给你两个数,(l,r)([l,r]) 中多少对 (a+b=aoplus b)

思路

看了大佬的题解才知道这里要用到二维容斥。
(f_{x,y})(ain [0,x],bin [0,y]) 时满足条件的对数
那么根据容斥原理答案就是 (f_{r,r}-f_{l-1,r} imes 2+f_{l-1,l-1})
对于其中每一部分都可以用一次数位DP求出来
因为这里对于统计有影响的因素只有两个数是否被限制
那么状态可以直接设计为 (dp_{pos,lim1,lim2})
代表在 (pos)(a,b) 是否被限制时的个数。

代码

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef long long LL;
int T,a[70],b[70];
LL f[70][2][2];

LL dfs(int pos,int lim1,int lim2){
    if(pos==-1) return 1;
    if(f[pos][lim1][lim2]!=-1) return f[pos][lim1][lim2];
    LL temp=0;
    int up1=lim1?a[pos]:1,up2=lim2?b[pos]:1;
    for(int i=0;i<=up1;i++)
        for(int j=0;j<=up2;j++){
            if(i==1&&j==1) continue;
            temp+=dfs(pos-1,lim1&&i==a[pos],lim2&&j==b[pos]);
        }
    f[pos][lim1][lim2]=temp;
    return temp;
}

LL solve(int x,int y){
    memset(f,-1,sizeof(f));
    int pos;
    for(pos=0;x||y;pos++,x/=2,y/=2)
        a[pos]=x%2,b[pos]=y%2;
    return dfs(pos-1,1,1);
}

int main(){
    scanf("%d",&T);
    int l,r;
    memset(f,-1,sizeof(f));
    while(T--){
        scanf("%d%d",&l,&r);
        printf("%lld
",solve(r,r)-2*solve(l-1,r)+solve(l-1,l-1));
    }
    return 0;
}

以上是关于Codeforces 1245F. Daniel and Spring Cleaning(容斥原理+数位DP)的主要内容,如果未能解决你的问题,请参考以下文章

CF1245F: Daniel and Spring Cleaning

CF1245F Daniel and Spring Cleaning(等会了更新)

CF1245F Daniel and Spring Cleaning(等会了更新)

codeforces - 1245 (div2)

CodeForces 1245D Shichikuji and Power Grid

并不对劲的CF1245E&F:Cleaning Ladders