水完小数据后,仔细想了想,绝对的数位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;
}