ARC 066D Xor Sum

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/81489235

因为a xor b = a + b - 2 (a & b)
从低位到高位用记忆化搜索实现数位DP

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define LL long long
#define mod 1000000007
#define hmod 300007
using namespace std;

LL n;
int info[300007],Prev[1000000],val[1000000],cnt_e;
LL key[2][1000000];

int Insert(LL u,LL v,int cst)
{
    int k = (u % hmod + v % hmod) % hmod;
    if(cst==-1)
    {
        for(int i=info[k];i;i=Prev[i])
            if(key[0][i] == u && key[1][i] == v)
                return val[i];
        return -1;
    }
    else Prev[++cnt_e] = info[k] , info[k] = cnt_e , val[cnt_e] = cst , key[0][cnt_e] = u , key[1][cnt_e] = v;
}

int dfs(LL u,LL v)
{
    if(v<0) return 0;
    if(v==0) return 1;
    LL tmp;
    if((tmp=Insert(u,v,-1))!=-1) return tmp;
    tmp = ((dfs(u >> 1 ,v >> 1) + dfs((u-1) >> 1 , (v-1) >> 1)) % mod + dfs(u>>1 , (v-2)>>1)) % mod;
    // 从低到高枚举数位,三种情况:a & 1 == b & 1 = 0 , (a & 1 == 1) ^ (b & 1 == 1) = 1 , a & 1 == b & 1 = 1
    Insert(u,v,tmp);
    return tmp;
}

int main()
{
    scanf("%lld",&n);
    printf("%d",dfs(n,n));
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/81489235