[SDOI2016]储能表
Description
有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号。每个格子都储存着能量。最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量。所以,整个表格储存的总能量是,
Input
第一行一个整数 T,表示数据组数。接下来 T 行,每行四个整数 n、m、k、p。
Output
共 T 行,每行一个数,表示总能量对 p 取模后的结果
Sample Input
2 2 0 100
3 3 0 100
3 3 1 100
Sample Output
12
6
HINT
T=5000,n≤10^18,m≤10^18,k≤10^18,p≤10^9
令$f[i][a][b][c]和g[i][a][b][c]$表示第i位,表示x后i-1位是否等于n,y后i-1位是否等于m,x^y后i-1位是否等于k的异或和以及方案数
如果a==1,且第i位大于n的第i位,那么超过上界,舍去
b同理
c比较特殊,如果c==1,如果第i为小于k的第i位,那么异或结果必定小于k,答案为0,舍去
$g[i][a][b][c]+=g[i-1][aa][bb][cc]$
$f[i][a][b][c]+=f[i-1][aa][bb][cc]+[第i位异或值为1]*2^{i}*g[i-1][aa][bb][cc]$
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
lol f[][][][],g[][][][],n,m,Mod,k,pw[],t1,t2,S,t3;
void dfs(lol x,int a,int b,int c)
{lol i,j;
if (f[x][a][b][c]!=-||g[x][a][b][c]!=-) return;
g[x][a][b][c]=f[x][a][b][c]=;
if (x==)
{
f[][a][b][c]=;
g[][a][b][c]=;
return;
}
for (i=;i<=;i++)
{
int xx=(n>>x-)&;
int yy=(m>>x-)&;
int zz=(k>>x-)&;
if (a&&i>xx) continue;
for (j=;j<=;j++)
{
if (b&&j>yy) continue;
lol p=i^j;
if (c&&p<zz) continue;
int aa=a&(xx==i);
int bb=b&(yy==j);
int cc=c&(zz==p);
dfs(x-,aa,bb,cc);
g[x][a][b][c]=(g[x][a][b][c]+g[x-][aa][bb][cc])%Mod;
f[x][a][b][c]=((f[x][a][b][c]+g[x-][aa][bb][cc]*p*(pw[x-]%Mod)%Mod)%Mod+f[x-][aa][bb][cc])%Mod;
}
}
}
lol solve()
{
memset(f,-,sizeof(f));
memset(g,-,sizeof(g));
t1=;S=n;
if (n==&&m==) return ;
while (S)
{
S>>=;
t1++;
}
t2=;S=m;
while (S)
{
S>>=;
t2++;
}
t3=;S=k;
while (S)
{
S>>=;
t3++;
}
t1=max(t1,max(t2,t3));
dfs(t1,,,);
return f[t1][][][]-(k%Mod)*g[t1][][][]%Mod;
}
int main()
{int T,i;
cin>>T;
pw[]=;
for (i=;i<=;i++)
pw[i]=pw[i-]*;
while (T--)
{
cin>>n>>m>>k>>Mod;
n--;m--;
printf("%lld\n",(solve()+Mod)%Mod);
}
}
[SDOI2016]储能表的更多相关文章
- BZOJ 4513: [Sdoi2016]储能表 [数位DP !]
4513: [Sdoi2016]储能表 题意:求\[ \sum_{i=0}^{n-1}\sum_{j=0}^{m-1} max((i\oplus j)-k,0) \] 写出来好开心啊...虽然思路不完 ...
- 4513: [Sdoi2016]储能表
4513: [Sdoi2016]储能表 链接 分析: 数位dp. 横坐标和纵坐标一起数位dp,分别记录当前横纵坐标中这一位是否受n或m的限制,在记录一维表示当前是否已经大于k了. 然后需要两个数组记录 ...
- 【LG4067】[SDOI2016]储能表
[LG4067][SDOI2016]储能表 题面 洛谷 题解 这种$n$.$m$出奇的大的题目一看就是数位$dp$啦 其实就是用一下数位$dp$的套路 设$f[o][n][m][k]$表示当前做到第$ ...
- 【BZOJ4513】[Sdoi2016]储能表 数位DP
[BZOJ4513][Sdoi2016]储能表 Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 ...
- BZOJ4513 SDOI2016 储能表 记忆化搜索(动态规划)
题意: 题面中文,不予翻译:SDOI2016储能表 分析: 据说有大爷用一些奇怪的方法切掉了这道题%%%%% 这里用的是大众方法——动态规划. 其实这是一道类似于二进制数位dp的动态规划题,(但是实际 ...
- BZOJ4513: [Sdoi2016]储能表
Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量. ...
- 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上界,是否 ...
随机推荐
- 《统计学习方法》P89页IIS的中间步骤Zw+δ(X)/Zw(X)的推导
共有两个方法:
- C语言博客作业--一二维数组。
一.PTA实验作业 题目1:7-1 将数组中的数逆序存放 1. 本题PTA提交列表 2. 设计思路 定义三个整型变量n用来存放整数个数i,j是循环数 scanf("%d",& ...
- 限定 edittext 的 输入内容
<EditText android:id="@+id/idNumber" style="@style ...
- IOS UITextView自适应高度
LOFTER app需要实现了一个类似iPhone短信输入框的功能,它的功能其实蛮简单,就是:[UITextView的高度随着内容高度的变化而变化].实现思路应该是: 在UITextView的text ...
- RxSwift 函数响应式编程
Max 在 Boston 上学,在 San Francisco 工作,是一名软件工程师及创业者.当他还在高中的时候就在一家创业公司工作了,他非常喜欢使用 iOS.Android 以及 JavaScri ...
- session 与 cookie (一)
服务器信息临时存储 session篇 web.xml设置 <session-config> <session-timeout></session-timeout> ...
- 新概念英语(1-11)Is this your shirt ?
Is this your shirt?Whose shirt is white? A:Whose shirt is that? Is this your shirt, Dave? Dave:No si ...
- 转:java中Vector的使用
转:https://www.cnblogs.com/zhaoyan001/p/6077492.html Vector 可实现自动增长的对象数组. java.util.vector提供了向量类(vect ...
- pandas.read_csv参数详解
读取CSV(逗号分割)文件到DataFrame 也支持文件的部分导入和选择迭代 更多帮助参见:http://pandas.pydata.org/pandas-docs/stable/io.html 参 ...
- pandas笔记
axis = 1表示按列的方向遍历 axis = 0表示按行的方向遍历 Usually axis=0 is said to be "column-wise" (and axis=1 ...