题意

题目链接

Sol

一点思路都没有,只会暴力,没想到标算是数位dp??Orz

首先答案可以分成两部分来统计

\[f_{i,j}=
\begin{aligned}
i\oplus j &\left( i\oplus j >k\right) \\
0 &\left( i\oplus j <=k\right)
\end{aligned}
\]

那么我们要求的就是

\[\sum_{i=0}^{n - 1} \sum_{j = 0}^{m - 1} f(i, j) - k * \sum_{i = 0}^{n - 1} \sum_{j = 0}^{m - 1} [f(i, j)]
\]

也就是说,我们要统计出满足条件的数的异或和以及满足条件的数的对数

考虑直接在二进制下数位dp,注意这里我们要记三维状态

\(f[len][0/1][0/1][0/1]\)表示此时到第\(len\)位,是否顶着\(n\)的上界,是否顶着\(m\)的上界,是否顶着\(k\)的下界

然后直接dp就可以了

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define Pair pair<LL, LL>
#define MP make_pair
#define fi first
#define se second
#define LL long long
#define int long long
using namespace std;
const int MAXN = 233;
inline LL read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
LL N, M, K, mod, Lim, vis[MAXN][2][2][2];
Pair f[MAXN][2][2][2];
void add2(LL &x, LL y) {
if(x + y < 0) x = (x + y + mod);
else x = (x + y >= mod ? x + y - mod : x + y);
}
LL add(LL x, LL y) {
if(x + y < 0) return x + y + mod;
return x + y >= mod ? x + y - mod : x + y;
}
LL mul(LL x, LL y) {
return 1ll * x % mod * y % mod;
}
int Get(LL x) {
int len = 0; while(x) x >>= 1, len++; return len;
}
Pair dfs(int now, int f1, int f2, int f3) {
if(now > Lim) return MP(0, 1);
if(vis[now][f1][f2][f3]) return f[now][f1][f2][f3];
vis[now][f1][f2][f3] = 1;
Pair ans = MP(0, 0);
int L1 = (N >> Lim - now) & 1, L2 = (M >> Lim - now) & 1, L3 = (K >> Lim - now) & 1;
//cout << (f1 &&(!L1)) << endl;
for(int i = 0; i <= (f1 ? L1 : 1); i++) {
for(int j = 0; j <= (f2 ? L2 : 1); j++) {
if(f3 && ((i ^ j) < L3)) continue;
Pair nxt = dfs(now + 1, f1 && (i == L1), f2 && (j == L2), f3 && ((i ^ j) == L3));
add2(ans.se, nxt.se);
add2(ans.fi, add(nxt.fi, mul(nxt.se, mul((i ^ j), (1ll << Lim - now)))));
}
}
return f[now][f1][f2][f3] = ans;
}
int solve() {
memset(vis, 0, sizeof(vis));
memset(f, 0, sizeof(f));
Lim = 0;
N = read(); M = read(); K = read(); mod = read(); N--; M--;
Lim = max(Get(N), max(Get(K), Get(M)));
Pair ans = dfs(1, 1, 1, 1);
return add(ans.fi, -mul(K, ans.se));
}
signed main() {
for(int T = read(); T; T--, printf("%lld\n", solve()));
return 0;
}
/*
5000
504363800392059286 554192717354508770 21453916680846604 401134357
*/

BZOJ4513: [Sdoi2016]储能表(数位dp)的更多相关文章

  1. [bzoj4513][SDOI2016]储能表——数位dp

    题目大意 求 \[\sum_{i = 0}^{n-1}\sum_{j=0}^{m-1} max((i\ xor\ j)\ -\ k,\ 0)\ mod\ p\] 题解 首先,开始并没有看出来这是数位d ...

  2. 【BZOJ4513】[Sdoi2016]储能表 数位DP

    [BZOJ4513][Sdoi2016]储能表 Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 ...

  3. BZOJ 4513: [Sdoi2016]储能表 [数位DP !]

    4513: [Sdoi2016]储能表 题意:求\[ \sum_{i=0}^{n-1}\sum_{j=0}^{m-1} max((i\oplus j)-k,0) \] 写出来好开心啊...虽然思路不完 ...

  4. BZOJ.4513.[SDOI2016]储能表(数位DP)

    BZOJ 洛谷 切了一道简单的数位DP,终于有些没白做题的感觉了...(然而mjt更强没做过这类的题也切了orz) 看部分分,如果\(k=0\),就是求\(\sum_{i=0}^n\sum_{j=0} ...

  5. [SDOI2016]储能表——数位DP

    挺隐蔽的数位DP.少见 其实减到0不减了挺难处理.....然后就懵了. 其实换个思路: xor小于k的哪些都没了, 只要留下(i^j)大于等于k的那些数的和以及个数, 和-个数*k就是答案 数位DP即 ...

  6. 4513: [Sdoi2016]储能表 数位DP

    国际惯例的题面: 听说这题的正解是找什么规律,数位DP是暴力......好的,我就写暴力了QAQ.我们令f[i][la][lb][lc]表示二进制从高到低考虑位数为i(最低位为1),是否顶n上界,是否 ...

  7. BZOJ4513 SDOI2016 储能表 记忆化搜索(动态规划)

    题意: 题面中文,不予翻译:SDOI2016储能表 分析: 据说有大爷用一些奇怪的方法切掉了这道题%%%%% 这里用的是大众方法——动态规划. 其实这是一道类似于二进制数位dp的动态规划题,(但是实际 ...

  8. BZOJ4513 SDOI2016储能表(数位dp)

    如果n.m.k都是2的幂次方,答案非常好统计.于是容易想到数位dp,考虑每一位是否卡限制即可,即设f[i][0/1][0/1][0/1]为第i位是/否卡n.m.k的限制时,之前的位的总贡献:g[i][ ...

  9. BZOJ4513: [Sdoi2016]储能表

    Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量. ...

随机推荐

  1. oracle创建表空间、用户、权限

    原链接:https://www.cnblogs.com/wxm-bk/p/6510654.html oracle 创建临时表空间/表空间,用户及授权   1:创建临时表空间 create tempor ...

  2. Ubuntu下解决apt update时签名无效问题

    Ubuntu 18.04在执行apt-get update时出现一下报错: W: GPG 错误:http://repo.mysql.com/apt/ubuntu bionic InRelease: 下 ...

  3. 禅道与bugfree区别

    bugfree更偏重bug管理, 禅道是以项目管理为目标, 所以出发点不一样. 我们bug追踪管理使用bugfree,项目管理计划使用禅道,配置管理使用svn bugfree很low,安装需要环境特别 ...

  4. 洛谷 P2015 二叉苹果树 (树上背包)

    洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...

  5. Vue项目开发目录结构

    最近做一些CI+Vue开发的简单项目,由于刚开始一直从事后端,对Vue了解不是很多,fork了团队的项目代码发现项目的文件夹很多,一时间有些懵,上网上参考了部分资料,博客园中的放晴的天空与狮子爱吃草两 ...

  6. (转)OpenStack各服务所用端口号总结

    参考:Firewalls and default ports 注:可执行 sudo netstat -tnlp 查看 端口 服务描述 22 SSH 3306 MariaDB(MySQL) 27017 ...

  7. web前端优化之reflow(减少页面的回流)

    1.什么是reflow? reflow(回流)是指浏览器为了重新渲染部分或者全部的文档,重新计算文档中的元素的位置和几何构造的过程. 因为回流可能导致整个Dom树的重新构造,所以是性能的一大杀手. 以 ...

  8. Spring Security OAuth 2开发者指南译

    Spring Security OAuth 2开发者指南译 介绍 这是用户指南的支持OAuth 2.0.对于OAuth 1.0,一切都是不同的,所以看到它的用户指南. 本用户指南分为两部分,第一部分为 ...

  9. java.util.Collections.synchronizedSet()方法的使用

    下面的例子显示java.util.Collections.synchronizedSet()方法的使用 package com.; import java.util.*; public class C ...

  10. Ubuntu14.04下Ambari安装搭建部署大数据集群(图文分五大步详解)(博主强烈推荐)

    不多说,直接上干货! 写在前面的话 (1) 最近一段时间,因担任我团队实验室的大数据环境集群真实物理机器工作,至此,本人秉持负责.认真和细心的态度,先分别在虚拟机上模拟搭建ambari(基于CentO ...