bzoj4513 储能表

Posted kong-ruo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4513 储能表相关的知识,希望对你有一定的参考价值。

求 $sumlimits_{i=0}^{n-1} sumlimits_{j=0}^{m-1} max((x space xor space j) - k,0)$ ,膜 $p$

$n,m leq 10^{18},p leq 10^9$,有 $5000$ 组数据

sol:

老年选手不会找规律,大力数位 dp

$F_{(i,n1,m1,k1)}$ 为考虑前 $i$ 位,是否卡 $n$ 的上界,是否卡 $m$ 的上界,是否卡 $k$ 的上界的所有 $(i,j)$ 异或和

$G_{(i,n1,m1,k1)}$ 为考虑前 $i$ 位,是否卡 $n$ 的上界,是否卡 $m$ 的上界,是否卡 $k$ 的上界的所有 $(i,j)$ 方案数

转移的时候讨论都不用讨论

技术图片
#include<bits/stdc++.h>
#define LL long long
#define rep(i,s,t) for(register int i = (s),i##end = (t); i <= i##end; ++i)
#define dwn(i,s,t) for(register int i = (s),i##end = (t); i >= i##end; --i)
using namespace std;
inline LL read()
{
    LL x=0,f=1;char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())if(ch==-)f=-f;
    for(;isdigit(ch);ch=getchar())x=10*x+ch-0;
    return x*f;
}
#define pii pair<LL, LL> 
#define FS first
#define SC second
int p,mxlen;
int vis[70][2][2][2];
pii f[70][2][2][2];
LL n,m,k;
void cal(LL n) {
    LL tmp = n;
    int cnt = 0;
    while(tmp) tmp>>=1,cnt++;
    mxlen = max(mxlen,cnt);
}
void inc(LL &x, LL y) {
    x += y;
    if (x >= p) x -= p;
}
pii dfs(int len,int n1,int m1,int k1){
    if (len>mxlen) return make_pair(1,0);
    if (vis[len][n1][m1][k1]) return f[len][n1][m1][k1];
    vis[len][n1][m1][k1] = 1;
    int nn=(n>>(mxlen-len))&1,mm=(m>>(mxlen-len))&1,kk=(k>>(mxlen-len))&1;
    for (int i=0;i<=(n1?nn:1);i++)
        for (int j=0;j<=(m1?mm:1);j++){
            if (k1 && (i^j)<kk) continue;
            pii tmp=dfs(len+1,n1&&(i==nn),m1&&(j==mm),k1&&((i^j)==kk));
            inc(f[len][n1][m1][k1].FS,tmp.FS);
            inc(f[len][n1][m1][k1].SC,((1ll<<(mxlen-len))*(i^j)%p*tmp.FS%p+tmp.SC)%p);
        }
    return f[len][n1][m1][k1];
}
LL solve(LL n, LL m, LL k) {
    memset(f, 0, sizeof(f));
    memset(vis, 0, sizeof(vis));
    mxlen = 0;
    cal(n); cal(m); cal(k);
    pii ans = dfs(1, 1, 1, 1); 
    return ((ans.SC % p - k % p * ans.FS % p + p) % p);
}
int main(){
    int T = read();
    while (T--) {
        n = read() - 1, m = read() - 1, k = read(), p = read();
        printf("%lld
", solve(n, m, k));
    }
}
View Code

 

以上是关于bzoj4513 储能表的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4513[Sdoi2016]储能表 数位DP

BZOJ 4513: [Sdoi2016]储能表

搜索(四分树):BZOJ 4513 [SDOI2016 Round1] 储能表

4513: [Sdoi2016]储能表

BZOJ4513~4518 SDOI2016 R1 题解

4513: [Sdoi2016]储能表 数位DP