BZOJ4513: [Sdoi2016]储能表(数位dp)
题意
Sol
一点思路都没有,只会暴力,没想到标算是数位dp??Orz
首先答案可以分成两部分来统计
设
\begin{aligned}
i\oplus j &\left( i\oplus j >k\right) \\
0 &\left( i\oplus j <=k\right)
\end{aligned}
\]
那么我们要求的就是
\]
也就是说,我们要统计出满足条件的数的异或和以及满足条件的数的对数
考虑直接在二进制下数位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)的更多相关文章
- [bzoj4513][SDOI2016]储能表——数位dp
题目大意 求 \[\sum_{i = 0}^{n-1}\sum_{j=0}^{m-1} max((i\ xor\ j)\ -\ k,\ 0)\ mod\ p\] 题解 首先,开始并没有看出来这是数位d ...
- 【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) 点能量. ...
随机推荐
- 考试题T3
题意分析 这题一看没有什么思路 幸好我们机房的红太阳\(ghj1222\)切了这道题 首先我们考虑风跑一个来回之后人怎么样 就是跑了一个区间 也就是风跑了若干个来回之后 人跑了若干个区间 所以我们考虑 ...
- 架构师养成记--23.sigar使用实例
作用是检测机器的硬件环境 注意在jdk的bin目录下加上sigar的lib目录中的文件 import java.net.InetAddress; import java.net.UnknownHost ...
- 使用scp命令,远程上传下载文件/文件夹
1.从服务器下载文件 scp username@servername:/path/filename /local/path例如: scp ubuntu@117.50.20.56:/ygf/data/d ...
- FileRecv VNCViewer 使用方法
版本 区别 一路点点点 . 就ok了 看到这个页面 点击 vnc viewer 输入 老师 会告诉你 IP地址 点击 就ok
- 《python灰帽子》学习笔记:调试器设置
一.构造 C 数据类型 C Type | Python Type | ctypes Type ____________________________________________________ ...
- Could not find a version that satisfies.... No matching distribution found for .....
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/10227403.html 今天在安装mysql-python的时候报了很多的错误,其中一条就是这 ...
- 向已有的table中插入数据
table: <table id="seleted-table" class="table table-bordered table-hover" sty ...
- js 页面间的通信
看了一下公司原来的代码,原页面ajax post返回一个页面完整的HTML,然后再打开一个新页面并输出ajax返回的所有代码到新页面上,在新页面上以表单提交的形式实现重定向. 任凭我想了半天也没想出来 ...
- unity多线程
多线程概念 多线程,是指实现多个线程并发执行的技术,合理利用多线程可以提升程序的性能,在unity中,一般是避免使用多线程的,unity对多线程的支持并不友好. 协程概念 协程,是指在主线程运行时开启 ...
- [转]SSRS: Checking for Divide By Zero Using Custom Code
本文转自:http://salvoz.com/blog/2011/11/25/ssrs-checking-for-divide-by-zero-using-custom-code/ I encount ...