省选被这题虐。。。前段时间推了一晚上终于推出dp式子;
正解是去发现神奇性质,然而数位dp也可以过;
#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=n;i++)
#define rep2(i,k,n) for(int i=k;i>=n;i--)
using namespace std;
const int N=105;
typedef long long ll;
ll T,n,m,k,p,f[N][2][2][2],g[N][2][2][2],bin[N];//low to high f[len][n][m][k]
int a[N],b[N],c[N];
void upd(ll& x,ll y){
x+=y;while(x>=p)x-=p;
}
void init(){
bin[1]=1;rep(i,2,63)bin[i]=(bin[i-1]<<1)%p;
rep(i,1,63)a[i]=(n>>(i-1))&1;
rep(i,1,63)b[i]=(m>>(i-1))&1;
rep(i,1,63)c[i]=(k>>(i-1))&1;
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
}
void solve(){
f[0][0][0][1]=f[0][1][0][1]=f[0][0][1][1]=f[0][1][1][1]=1;
rep(l,0,62){
rep(d1,0,1)rep(d2,0,1)rep(kk,0,1)if(f[l][d1][d2][kk]){
ll res=f[l][d1][d2][kk];
ll res2=g[l][d1][d2][kk];
rep(c1,0,1)rep(c2,0,1){
int op_k=((c1^c2)>c[l+1] ? 1 : ((c1^c2)==c[l+1] && kk));
int op_n=(((d1 && c1==a[l+1])||(!d1 && c1<a[l+1]))<<1)|(d1^1);
int op_m=(((d2 && c2==b[l+1])||(!d2 && c2<b[l+1]))<<1)|(d2^1);
rep(to_n,0,1)rep(to_m,0,1)
if(((op_n>>to_n)&1) && ((op_m>>to_m)&1)){
upd(f[l+1][to_n][to_m][op_k],res);
upd(g[l+1][to_n][to_m][op_k],(res*(c1^c2)*bin[l+1]%p+res2)%p);
}
}
}
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld%lld%lld%lld",&n,&m,&k,&p);n--,m--;
init();
solve();
ll ans=g[63][1][1][1]-(k%p)*f[63][1][1][1]%p;
while(ans<0)ans+=p;
printf("%lld\n",ans);
}
// rep(i,1,63)printf("%lld\n",g[i][1][1][1]);
}