[SDOI2016]储能表

题目

数位\(dp\)思博题啊

但是我更加思博啊

面对\(10^{18}\)的数据范围,我竟然只开了\(19\)的数据,而这是一道二进制数位\(dp\)

我们设\(f[i][0/1][0/1][0/1]\)表示进行到了第\(i\)位,不卡/卡\(n\)的上界,不卡/卡\(m\)的上界,不卡/卡\(k\)的下界,我们求出所有异或值大于\(k\)的数的和,和方案数随便搞一搞就出来了

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline LL read() {
	char c=getchar();LL x=0;while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int T;
LL n,m,K,mod;
LL dp[67][2][2][2],f[67][2][2][2],pw[67];
int a[67],b[67],c[67];
inline void countBit(LL x,int *g) {
	int tot=0;
	while(x) {g[tot++]=(x&1ll);x>>=1ll;}
}
int main() {
	T=read();
	while(T--) {
		n=read(),m=read(),K=read(),mod=read();
		if(n>m) std::swap(n,m);
		n--,m--;
		memset(dp,0,sizeof(dp));
		memset(f,0,sizeof(f));
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(c,0,sizeof(c));
		memset(pw,0,sizeof(pw));
		pw[0]=1;
		for(re int i=1;i<=65;i++) pw[i]=(pw[i-1]+pw[i-1])%mod;
		countBit(n,a),countBit(m,b),countBit(K,c);
		f[66][1][1][1]=1;
		for(re int i=65;i>=0;--i)
			for(re int j=0;j<2;j++)
				for(re int k=0;k<2;k++)
					for(re int p=0;p<2;p++) {
						for(re int t=0;t<2;t++)
							for(re int h=0;h<2;h++) {
								if(j&&t>a[i]) continue;
								if(k&&h>b[i]) continue;
								if(p&&(t^h)<c[i]) continue;
								int o1=j;
								if(o1) if(t<a[i]) o1=0;
								int o2=k;
								if(o2) if(h<b[i]) o2=0;
								int o3=p;
								if(o3) if((t^h)>c[i]) o3=0;
								f[i][o1][o2][o3]=(f[i][o1][o2][o3]+f[i+1][j][k][p])%mod;
								dp[i][o1][o2][o3]=(dp[i][o1][o2][o3]+dp[i+1][j][k][p])%mod;
								if(h^t) 
									dp[i][o1][o2][o3]=(dp[i][o1][o2][o3]+f[i+1][j][k][p]*pw[i]%mod)%mod;
							}
					}
		LL ans=0,cnt=0;
		for(re int i=0;i<2;i++)
			for(re int j=0;j<2;j++)
				for(re int k=0;k<2;k++)
					ans=(ans+dp[0][i][j][k])%mod,cnt=(cnt+f[0][i][j][k])%mod;
		K%=mod;
		printf("%lld\n",(ans-cnt*K%mod+mod)%mod);	
	}
	return 0;
}
posted @ 2019-03-31 21:52  asuldb  阅读(293)  评论(0编辑  收藏  举报