水完小数据后,仔细想了想,绝对的数位DP啊,我去。
推式子,写代码,一气呵成啊我去,结果坑在memset上了我去,还不如让我没有思路。
上图。。
可以看到sizeof(num) == 4,sizeof(w) == 52。
也就是说此时num虽然也指向w[0]。但是仅代表着w[0]这个元素,并不代表这个数组。
先暂且这样理解着吧,坐等大神来指导。
好了废话不说了,很简单的数位DP,发在这里只是为了提醒一下memset,不是自己写的函数要慎用啊。
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long LL #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 1000000007 #define LM(a,b) (((ULL)(a))<<(b)) #define RM(a,b) (((ULL)(a))>>(b)) using namespace std; LL dp[35][2][2][2]; int a[35],b[35],k[35]; int Init(int *num,LL x) { int len = 0; LL temp = x; while(temp) { ++len; temp /= 2; } int i; temp = x; for(i = 0; i < len; ++i) { num[32-i] = temp%2; temp /= 2; } return len; } LL dfs(bool ta,bool tb,bool tk,int site,int Top) { int sa = (ta == true ? 1 : 0); int sb = (tb == true ? 1 : 0); int sk = (tk == true ? 1 : 0); if(site == Top+1) { return 1; } if(dp[site][sa][sb][sk] != -1) return dp[site][sa][sb][sk]; LL ans = 0; int pa,pb,i,j; if(tk == true) { if(k[site] == 1) { if(a[site] == 1 || ta == false) pa = 1; else pa = 0; if(b[site] == 1 || tb == false) pb = 1; else pb = 0; for(i = 0; i <= pa; ++i) { for(j = 0; j <= pb; ++j) { ans += dfs(ta && i == pa ,tb && j == pb,tk && (i&j) == k[site],site+1,Top); } } } else { if(a[site] == 1 || ta == false) pa = 1; else pa = 0; if(b[site] == 1 || tb == false) pb = 1; else pb = 0; for(i = 0; i <= pa; ++i) { for(j = 0; j <= pb; ++j) { if((i&j) == 0) { ans += dfs(ta && i == pa ,tb && j == pb,true,site+1,Top); } } } } } else { if(a[site] == 1 || ta == false) pa = 1; else pa = 0; if(b[site] == 1 || tb == false) pb = 1; else pb = 0; for(i = 0; i <= pa; ++i) { for(j = 0; j <= pb; ++j) { ans += dfs(ta && i == pa ,tb && j == pb,false,site+1,Top); } } } dp[site][sa][sb][sk] = ans; return ans; } LL Cal(LL A,LL B,LL K) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(k,0,sizeof(k)); int la = Init(a,A); int lb = Init(b,B); int lk = Init(k,K); if(la == 0) la = 1; if(lb == 0) lb = 1; if(lk == 0) lk = 1; int L = max(la,max(lb,lk)); memset(dp,-1,sizeof(dp)); return dfs(true,true,true,32-L+1,32); } int main() { //freopen("B-large-practice.in","r",stdin); //freopen("B-large-practice.out","w",stdout); LL a,b,k; int T; scanf("%d",&T); int icase = 1; while(T--) { scanf("%lld %lld %lld",&a,&b,&k); a--,b--,k--; printf("Case #%d: ",icase++); cout<<Cal(a,b,k)<<endl; } return 0; }