QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#824702#6655. 巧克力rqoi031AC ✓242ms1648kbC++202.2kb2024-12-21 15:20:022024-12-21 15:20:10

Judging History

你现在查看的是最新测评结果

  • [2024-12-21 15:20:10]
  • 评测
  • 测评结果:AC
  • 用时:242ms
  • 内存:1648kb
  • [2024-12-21 15:20:02]
  • 提交

answer

#include<stdio.h>
#include<algorithm>
#include<cstring>
typedef unsigned int uint;
typedef unsigned long long ull;
constexpr uint mod{1000000007};
constexpr uint plus(const uint &x,const uint &y) {
    if(x+y>=mod) {
        return x+y-mod;
    }
    return x+y;
}
namespace DP1 {
    uint dp[61][2][3];
    int vis[61][2][3];
    uint dfs(const ull &n,const ull &v,const int &cur,const int &lim,const int &rem) {
        if(cur==-1) {
            return rem>0;
        }
        if(vis[cur][lim][rem]) {
            return dp[cur][lim][rem];
        }
        uint res{0};
        int up{lim?int(n>>cur&1):1};
        for(int i=0;i<=up;i++) {
            for(int a=0;a<=1;a++) {
                int b{int(v>>cur&1)^i^a};
                if((rem<<1)+i>=a+b) {
                    res=plus(res,dfs(n,v,cur-1,lim&&i==up,std::min(2,(rem<<1)+i-a-b)));
                }
            }
        }
        vis[cur][lim][rem]=1;
        dp[cur][lim][rem]=res;
        return res;
    }
    uint calc(const ull &n,const ull &v) {
        std::memset(dp,0,sizeof(dp));
        std::memset(vis,0,sizeof(vis));
        return dfs(n,v,60,1,0);
    }
}
namespace DP2 {
    uint dp[61][3];
    int vis[61][3];
    uint dfs(const ull &n,const ull &v,const int &cur,const int &rem) {
        if(cur==-1) {
            return rem>0;
        }
        if(vis[cur][rem]) {
            return dp[cur][rem];
        }
        uint res{0};
        int i{int(n>>cur&1)};
        for(int a=0;a<=1;a++) {
            int b{int(v>>cur&1)^i^a};
            if((rem<<1)+i>=a+b) {
                res=plus(res,dfs(n,v,cur-1,std::min(2,(rem<<1)+i-a-b)));
            }
        }
        vis[cur][rem]=1;
        dp[cur][rem]=res;
        return res;
    }
    uint calc(const ull &n,const ull &v) {
        std::memset(dp,0,sizeof(dp));
        std::memset(vis,0,sizeof(vis));
        return dfs(n,v,60,0);
    }
}
void solve() {
    ull n,m;
    scanf("%llu%llu",&n,&m);
    ull v{(n==0?0:(n&1?0:n)^(n-1>>1&1^1))^m};
    if(v==0) {
        return puts("0"),void();
    }
    printf("%u\n",plus(DP1::calc(n,v),DP2::calc(m,v)));
}
int main() {
    int t;
    scanf("%d",&t);
    while(t--) {
        solve();
    }
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 242ms
memory: 1648kb

input:

50000
0 0
0 1
0 2
0 3
0 4
0 5
1 0
1 1
1 2
1 3
1 4
1 5
2 0
2 1
2 2
2 3
2 4
2 5
3 0
3 1
3 2
3 3
3 4
3 5
4 0
4 1
4 2
4 3
4 4
4 5
5 0
5 1
5 2
5 3
5 4
5 5
0 2000000013
3 2000000013
960420868510113883 392659194919473988
668803384430801620 162045456939453012
617795168362576047 722239203838631701
6050650100...

output:

0
1
1
2
2
3
1
0
2
2
2
2
2
1
1
0
4
4
0
4
4
6
2
3
2
2
2
4
0
5
5
0
6
5
7
6
0
0
617401866
87835503
788974705
719403921
388746468
343575572
346563231
107105273
892988359
21085898
256773311
736064559
221068497
268198252
311484988
140174338
95593482
477651660
154447963
420109896
648989232
806537128
7685205...

result:

ok 50000 numbers