【bzoj4513】[Sdoi2016]储能表 数位dp

我真TM是个sb!!!

f[i][0/1][0/1][0/1]表示考虑到第i位前i位是否卡n的上界,是否卡m的上界,是否卡k的下界的数对的个数

g[i][0/1][0/1][0/1]表示考虑到第i位前i位是否卡n的上界,是否卡m的上界,是否卡k的下界的数对的和

直接dp

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>

using namespace std;

long long f[110][2][2][2],g[110][2][2][2],bin[64];
long long n,m,mod,k;
int T;

int main()
{
	scanf("%d",&T);
	while (T--)
	{
		scanf("%lld%lld%lld%lld",&n,&m,&k,&mod);
		n--;m--;
		long long ans=0;
		bin[0]=1;
		for (int i=1;i<=63;i++) bin[i]=(long long)bin[i-1]*2ll%mod;
		memset(f,0,sizeof(f));
		memset(g,0,sizeof(g));
		f[0][1][1][1]=1;g[0][1][1][1]=0;
		for (int i=0;i<=63;i++)
		  for (int a=0;a<2;a++)
		    for (int b=0;b<2;b++)
		      for (int c=0;c<2;c++)
		        if (f[i][a][b][c])
		        {
		        	int p=((n&(1ll<<(63-i)))==0)?0:1;
		        	int q=((m&(1ll<<(63-i)))==0)?0:1;
		        	int t=((k&(1ll<<(63-i)))==0)?0:1;
		        	for (int x=0;x<2;x++)
		        	{
		        		if (a && x>p) continue;
		        		for (int y=0;y<2;y++)
		        		{
		        			if (b && y>q) continue;
		        			int z=x^y;
		        			if (c && z<t) continue;
		        			int A=(a && x==p)?1:0;
		        			int B=(b && y==q)?1:0;
		        			int C=(c && z==t)?1:0;
		        			f[i+1][A][B][C]=(f[i+1][A][B][C]+f[i][a][b][c])%mod;
		        			g[i+1][A][B][C]=(g[i+1][A][B][C]+g[i][a][b][c]+((z==0)?0:bin[63-i])*f[i][a][b][c]%mod)%mod;
		        		}
		        	}
		        }
		k%=mod;
		for (int a=0;a<2;a++)
		  for (int b=0;b<2;b++)
		    for (int c=0;c<2;c++)
		      ans=(ans+g[64][a][b][c]-k*f[64][a][b][c]%mod+mod)%mod;
		printf("%lld\n",ans);
	}
	return 0;
}
时间: 2024-10-04 16:48:27

【bzoj4513】[Sdoi2016]储能表 数位dp的相关文章

4513: [Sdoi2016]储能表

4513: [Sdoi2016]储能表 链接 分析: 数位dp. 横坐标和纵坐标一起数位dp,分别记录当前横纵坐标中这一位是否受n或m的限制,在记录一维表示当前是否已经大于k了. 然后需要两个数组记录答案,分别记录个数和答案的和. 语意不清了...看代码吧.. 代码: #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream>

BZOJ 4513: [Sdoi2016]储能表

Description 求\(\sum_{i=0}^{n-1}\sum_{i=0}^{n-1}max\{i\)^\(j-k,0\}\) \(n,m\leqslant 10^{18},k\leqslant 10^9\) Solution 数位DP. 我好弱啊qwq... \(f[i][na][nb][nc]\)表示枚举到第\(i\)位,是否卡\(n\)上界,是否卡\(m\)上界,是否卡\(k\)下界. 枚举\(i\)这一位01,\(j\)这一位01,枚举上一个状态,判断一下合法,计算转移后的状态,

[SDOI2016]储能表

题目 数位\(dp\)思博题啊 但是我更加思博啊 面对\(10^{18}\)的数据范围,我竟然只开了\(19\)的数据,而这是一道二进制数位\(dp\)啊 我们设\(f[i][0/1][0/1][0/1]\)表示进行到了第\(i\)位,不卡/卡\(n\)的上界,不卡/卡\(m\)的上界,不卡/卡\(k\)的下界,我们求出所有异或值大于\(k\)的数的和,和方案数随便搞一搞就出来了 代码 #include<algorithm> #include<iostream> #include&

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

4513: [Sdoi2016]储能表 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 395  Solved: 213[Submit][Status][Discuss] Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量.所以,整个表格储存的总能量是, 随着时间的推移,格子中的能量会渐渐减少.一个时间

HDU 5179 beautiful number (数位dp / 暴力打表 / dfs)

beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 801    Accepted Submission(s): 518 Problem Description Let A=∑ni=1ai?10n?i(1≤ai≤9)(n is the number of A's digits). We call A as "

hdu 5179(数位DP||打表)

beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 596    Accepted Submission(s): 370 Problem Description Let A=∑ni=1ai∗10n−i(1≤ai≤9)(n is the number of A's digits). We call A as “

HDU 4588 Count The Carries 数位DP || 打表找规律

2013年南京邀请赛的铜牌题...做的很是伤心,另外有两个不太好想到的地方....a 可以等于零,另外a到b的累加和比较大,大约在2^70左右. 首先说一下解题思路. 首先统计出每一位的1的个数,然后统一进位. 设最低位为1,次低位为2,依次类推,ans[]表示这一位上有多少个1,那么有 sum += ans[i]/2,ans[i+1] += ans[i]/2; sum即为答案. 好了,现在问题转化成怎么求ans[]了. 打表查规律比较神奇,上图不说话. 打表的代码 #include <algo

bzoj4513 储能表

求 $\sum\limits_{i=0}^{n-1} \sum\limits_{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

数位DP复习小结

之前学数位dp的时候底子没打扎实 虚的要死 这次正好有时间……刷了刷之前没做的题目 感觉自己脑洞不太够……比较经典的题或者见过的类似模型就能自己推出来,但是没有见过的模型就虚的要死(比如二进制数位DP) 感谢WQ的帮助,让我对数位DP的理解逐渐加深 那么我们总结一下这次做的题目…… bzoj4521 记忆化搜索即可,水爆 1 #include <cstring> 2 #include <cstdio> 3 using namespace std; 4 #define RG regi