首页 > 其他 > 详细

数位dp模板

时间:2016-01-18 16:07:47      阅读:188      评论:0      收藏:0      [点我收藏+]
#include <bits/stdc++.h>
typedef long long LL;

const int MOD = (int)1e9 + 7;
LL L,R,G,T;
int dp[62 + 1][2][2][2][2];
bool vis[62 + 1][2][2][2][2];

inline void add(int &a,int b) {
    a += b;
    if (a >= MOD) a -= MOD;
    if (a < 0) a += MOD;
}

int calc(int at,bool al,bool ar,bool bl,bool br) {
    if (at == -1) {
        return 1;
    }
    if (vis[at][al][ar][bl][br]) {
        return dp[at][al][ar][bl][br];
    }

    vis[at][al][ar][bl][br] = true;
    int &ret = dp[at][al][ar][bl][br];
    ret = 0;

    int l = L >> at & 1,
        r = R >> at & 1,
        x = (G ^ T) >> at & 1;
    for (int a = 0; a < 2; ++ a) {
        if (al && a < l) continue;
        if (ar && a > r) continue;
        int b = x ^ a;
        if (bl && b < l) continue;
        if (br && b > r) continue;
        add(ret,calc(at - 1,al && a == l,ar && a == r,bl && b == l,br && b == r));
    }
    return ret;
}

int work() {
    if ((G ^ T) == 0) return (R - L + 1) % MOD;
    memset(vis,false,sizeof(vis));
    return ((R - L + 1) * 2 % MOD - calc(62,true,true,true,true) + MOD) % MOD;
}

int main() {
    int cas;
    scanf("%d",&cas);
    while (cas--) {
        scanf("%I64d%I64d%I64d%I64d",&L,&R,&G,&T);
        printf("%d\n",work());
    }
}
GTW likes czf
从前,有两个人名叫GTW,DSY。一天,他们为了争夺DSY的妹子CZF,决定进行一次决斗。首先,CZF会给出一个区间l,l+1,l+2......rl,l+1,l+2......r,和两个数G,TG,T。现在,CZF会在G,TG,T两个数中随机一个数XX,在区间l,rl,r中随机一个数Y,进行一种特殊的运算@。CZF想要快速知道有多少数字可能会是答案。 然而GTW并不会做这道题,但是为了赢得CZF,他就来寻求你的帮助。 由于答案可能会很大,所以把最终的答案模1000000007。 我们规定运算X @ Y =((X and Y) or Y) xor X.

数位dp模板

原文:http://www.cnblogs.com/get-an-AC-everyday/p/5139519.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!