Problem Description
Zhu is a powerful ACMer/OverWatcher, now a salt-fish comes to ask Zhu a difficult problem. Zhu thinks that problem is so easy, so he wants to know whether you can solve it?
The problem content are as follows.
You are given four integers A , B , C , D , there are many different (a,b,c,d) satisfy a+c>b+d && a+d≥b+c && 0≤a≤A && 0≤b≤B && 0≤c≤C && 0≤d≤D ?
The problem content are as follows.
You are given four integers A , B , C , D , there are many different (a,b,c,d) satisfy a+c>b+d && a+d≥b+c && 0≤a≤A && 0≤b≤B && 0≤c≤C && 0≤d≤D ?
Input
First Line is an positive integer
T(T≤1000)
, represents there are T test cases.
Four each test:
The first line contain four integers A , B , C , D.
You can assume that 0≤A,B,C,D≤1018
Four each test:
The first line contain four integers A , B , C , D.
You can assume that 0≤A,B,C,D≤1018
Output
For each test case, output an positive integer represents answer, because the answer may be large , so you are only need to output answer mod
109+7
Sample Input
1 2 1 1 1
Sample Output
10
这题的做法服气。。
我们考虑按位枚举二进制
将字母移到一边,两个不等式分别是a+c-b-d>0和a+d-b-c>=0
假如枚举到len位,a+c-b-d>=2,那么就算a c剩下的都是0,b d剩下的都是1也可满足不等式
a+d-b-c>=0同理 不等式当前<=-2也同理
那么就可以考虑直接数位dp了
因为每位需要记录的不同的差只有5*5=25种
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long mod=1000000007;
long long f[70][16][5][5];
long long t[5];
inline long long dfs(int len,int lim,int x1,int x2)
{
if(len<0)
{
if(x1>0&&x2>=0)
return 1;
return 0;
}
if(f[len][lim][x1+2][x2+2]!=-1)
return f[len][lim][x1+2][x2+2];
int i,j,k,l;
int limit[5];
for(i=1;i<=4;i++)
{
if(((t[i]>>len)&1)==1||(lim&(1<<(i-1)))==(1<<(i-1)))
limit[i]=1;
else
limit[i]=0;
}
long long ans=0;
for(i=0;i<=limit[1];i++)
{
for(j=0;j<=limit[2];j++)
{
for(k=0;k<=limit[3];k++)
{
for(l=0;l<=limit[4];l++)
{
long long tx1,tx2;
tx1=x1*(long long)2+i+k-j-l;
tx2=x2*(long long)2+i+l-j-k;
if(tx1<=-2||tx2<=-2)
continue;
tx1=min(tx1,(long long)2);
tx2=min(tx2,(long long)2);
int xx=lim;
if(i!=limit[1]) xx|=(1<<0);
if(j!=limit[2]) xx|=(1<<1);
if(k!=limit[3]) xx|=(1<<2);
if(l!=limit[4]) xx|=(1<<3);
ans=(ans+dfs(len-1,xx,tx1,tx2))%mod;
}
}
}
}
f[len][lim][x1+2][x2+2]=ans;
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T>0)
{
T--;
scanf("%I64d%I64d%I64d%I64d",&t[1],&t[2],&t[3],&t[4]);
memset(f,-1,sizeof(f));
printf("%I64d\n",dfs(60,0,0,0));
}
return 0;
}