Find a car题解
Find a car题解
恶心题。
题目链接
首先规律就难以发现:
\(a[i][j]=(i-1)\)^\((j-1)+1 \sum_{i=1}^{x} \sum_{j=1}^{y} (a[i][j]<=k)\)
然后神奇数位DP,每一位枚举这一位是0,是1,是否满足i、j、k 的限制,(1为不满足,0为满足。)
#include<bits/stdc++.h>
#define ll long long
#define work(x,y,z) if(i>1||w==x) dfs2(i>>1,state,y,z,i>1?w^x:w)
using namespace std;
const ll mod=1e9+7;
int t,t1,t2,t3,t4,k;
ll q,fs[12],fc[12],gs[12],gc[12];
inline void add(ll &x){if(x>=mod)x-=mod;}
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
void dfs2(int i,int state,int u,int v,int w){
if(!i){
if(w) fs[v]=(fs[v]+q*gc[u])%mod;
add(fs[v]+=gs[u]); add(fc[v]+=gc[u]);
return;
}
if(i&state){work(0,u,v|i); work(1,u,v);}//有限制,这一位可以选1,可以选0
else work(0,u,v);//有限制,只能选0
work(0,u|i,v|i); work(1,u|i,v|i);//无限制,即可以选0,也可以选1
}//搜索这一位选择,满足x,y,z哪些的限制
ll dfs(ll x,ll y,ll z){
if(x<0||y<0||z<0) return 0;
ll ans=0;
memset(gc,0,sizeof(gc)),memset(gs,0,sizeof(gs)),gc[0]=1;
for(int i=(1<<30);i;i>>=1){
q=i,dfs2(4,(((x&i)>0)*4)|(((y&i)>0)*2)|((z&i)>0),0,0,0);//每一位的限制
memcpy(gc,fc,sizeof(fc)),memcpy(gs,fs,sizeof(fs));
memset(fc,0,sizeof(fc)),memset(fs,0,sizeof(fs));
}
for(int i=0;i<8;++i) add(ans+=gc[i]),add(ans+=gs[i]);
return ans;
}
int main(){
t=read();
while(t--){
t1=read()-2,t2=read()-2,t3=read()-1,t4=read()-1,k=read()-1;
printf("%lld\n",((dfs(t3,t4,k)-dfs(t1,t4,k)-dfs(t3,t2,k)+dfs(t1,t2,k))%mod+mod)%mod);
}
return 0;
}