[bzoj4513][SDOI2016]储能表——数位dp
题目大意
求
\]
题解
首先,开始并没有看出来这是数位dp。
后来发现可以一位一位的处理,每一位可以从前一位推出,所以可以考虑数位dp。
我们把要统计的数变为二进制表示,先考虑n位二进制的数,再考虑n-1位的数……,加起来就好辣。
定义f[i][1/0][1/0][1/0]为已经考虑到了第i位,第i位是否比n(第i位)小,第i位是否比m小,是否比k小的总共分数。
定义g[i][1/0][1/0][1/0]为已经考虑到了第i位,第i位是否比n(第i位)小,第i位是否比m小,是否比k小的所有情况总数。
我们从大到小考虑每一位,可以有,
g[i][aa][bb][cc] += g[i+1][a][b][c];
如果从状态(i,a,b,c)可以转移到状态(i-1, aa, bb, cc);
对于
f[i][aa][bb][cc] += f[i+1][a][b][c] + (zz-z)*(1<<i)*g[i+1][a][b][c];
前一项不必多说,后一项就是对于每一种可能都可以在前面加上1/0。
详细可以见代码。
有问题可以在评论区吐槽。。。
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll f[62][2][2][2], g[62][2][2][2]; //log2(10^18) = 60
ll n, m, k, T, p;
int main() {
scanf("%lld", &T);
while (T--) {
memset(f, 0, sizeof(f));
memset(g, 0, sizeof(g));
scanf("%lld %lld %lld %lld", &n, &m, &k, &p);
g[61][1][1][1] = 1;
for (int i = 60; i >= 0; i--) {
int x = (n >> i) & 1, y = (m >> i) & 1, z = (k >> i) & 1;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
for (int c = 0; c < 2; c++) {
if (f[i + 1][a][b][c] || g[i + 1][a][b][c]) {
for (int xx = 0; xx < 2; xx++) {
for (int yy = 0; yy < 2; yy++) {
int zz = xx ^ yy;
if ((a && x < xx) || (b && y < yy) || (c && z > zz))
continue;
int aa = (a && x == xx), bb = (b & y == yy),
cc = (c && z == zz);
g[i][aa][bb][cc] = (g[i][aa][bb][cc] + g[i + 1][a][b][c]) % p;
f[i][aa][bb][cc] = (f[i][aa][bb][cc] + f[i + 1][a][b][c] +
((zz - z) + p) % p * ((1ll << i) % p) %
p * g[i + 1][a][b][c] % p) %
p;
}
}
}
}
}
}
}
printf("%lld\n", f[0][0][0][0]);
}
}
[bzoj4513][SDOI2016]储能表——数位dp的更多相关文章
- BZOJ4513: [Sdoi2016]储能表(数位dp)
题意 题目链接 Sol 一点思路都没有,只会暴力,没想到标算是数位dp??Orz 首先答案可以分成两部分来统计 设 \[ f_{i,j}= \begin{aligned} i\oplus j & ...
- 【BZOJ4513】[Sdoi2016]储能表 数位DP
[BZOJ4513][Sdoi2016]储能表 Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 ...
- BZOJ 4513: [Sdoi2016]储能表 [数位DP !]
4513: [Sdoi2016]储能表 题意:求\[ \sum_{i=0}^{n-1}\sum_{j=0}^{m-1} max((i\oplus j)-k,0) \] 写出来好开心啊...虽然思路不完 ...
- BZOJ.4513.[SDOI2016]储能表(数位DP)
BZOJ 洛谷 切了一道简单的数位DP,终于有些没白做题的感觉了...(然而mjt更强没做过这类的题也切了orz) 看部分分,如果\(k=0\),就是求\(\sum_{i=0}^n\sum_{j=0} ...
- [SDOI2016]储能表——数位DP
挺隐蔽的数位DP.少见 其实减到0不减了挺难处理.....然后就懵了. 其实换个思路: xor小于k的哪些都没了, 只要留下(i^j)大于等于k的那些数的和以及个数, 和-个数*k就是答案 数位DP即 ...
- 4513: [Sdoi2016]储能表 数位DP
国际惯例的题面: 听说这题的正解是找什么规律,数位DP是暴力......好的,我就写暴力了QAQ.我们令f[i][la][lb][lc]表示二进制从高到低考虑位数为i(最低位为1),是否顶n上界,是否 ...
- BZOJ4513 SDOI2016 储能表 记忆化搜索(动态规划)
题意: 题面中文,不予翻译:SDOI2016储能表 分析: 据说有大爷用一些奇怪的方法切掉了这道题%%%%% 这里用的是大众方法——动态规划. 其实这是一道类似于二进制数位dp的动态规划题,(但是实际 ...
- BZOJ4513 SDOI2016储能表(数位dp)
如果n.m.k都是2的幂次方,答案非常好统计.于是容易想到数位dp,考虑每一位是否卡限制即可,即设f[i][0/1][0/1][0/1]为第i位是/否卡n.m.k的限制时,之前的位的总贡献:g[i][ ...
- BZOJ4513: [Sdoi2016]储能表
Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量. ...
随机推荐
- Hadoop环境搭建 (伪分布式搭建)
一,Hadoop版本下载 建议下载:Hadoop2.5.0 (虽然是老版本,但是在企业级别中运用非常稳定,新版本虽然添加了些小功能但是版本稳定性有带与考核) 1.下载地址: hadoop.apache ...
- 12,DBUtils - Python数据库连接池
创建数据库连接池: import time import pymysql import threading from DBUtils.PooledDB import PooledDB, SharedD ...
- JavaScript 仿ios滑动选择器
从git上找了一个,不过不是我想要的,更改了许多.到了我想要的效果: roller_selector_0_9.js 首先上js: "use strict"; /* * Author ...
- linux下创建用户 费元星站长
linux下创建用户(一) Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.用户的账号一方面可以帮助系 ...
- Tomcat详解及SNS系统的部署实现
Tomcat详解及SNS系统的部署实现 http://jungege.blog.51cto.com/4102814/1409290
- 【Validation】林轩田机器学习基石
这一节主要讲如何通过数据来合理的验证模型好不好. 首先,否定了Ein来选模型和Etest来选模型. (1)模型越复杂,Ein肯定越好:但是Eout就不一定了(见上一节的overfitting等) (2 ...
- es6实现简单模板编译
现在有各种框架,其中一个主要模块就是关于template.最火的vue.react等框架,在这一块上也是是下足了功夫.我也想写一个自己的模板编译工具,所以就做了个简单的实现,主要是使用es6的反引号编 ...
- linux系统下怎么关闭一个端口
netstat -an | grep 22查看22端口 netstat -ntulp |grep 80 //查看所有80端口使用情况
- python 学习分享-rabbitmq
一.RabbitMQ 消息队列介绍 RabbitMQ也是消息队列,那RabbitMQ和之前python的Queue有什么区别么? py 消息队列: 线程 queue(同一进程下线程之间进行交互) 进程 ...
- SDK支付流程
1.普通支付流程 2.代理流程 易接.U8SDK