二进制数位dp
https://codeforces.com/contest/1245/problem/F
求区间[L,R]中,a+b=a xor b 的a,b的组数
二进制数位dp,对于是否有限制,加入数组这一维度
第一发开始超时感觉很奇怪,dp数组只需要初始化一次,可能是因为二进制很多limit==true的情况吧,把这个加入数组状态就好啦。
LTE###
#include<bits/stdc++.h>
#define ll long long
const int N=32;
ll dp[N];
using namespace std;
ll dfs(int l,int r,int pos,bool limit1,bool limit2){
if(pos==-1)return 1;
if(limit1==0&&limit2==0&&dp[pos]!=-1)return dp[pos];
int up1=1,up2=1;
if(limit1)up1=(l>>pos)&1;
if(limit2)up2=(r>>pos)&1;
ll res=0;
for(int i=0;i<=up1;i++){
for(int j=0;j<=up2;j++){
if((i&j)==0)
res+=dfs(l,r,pos-1,limit1&(i==up1),limit2&(j==up2));
}
}
if(limit1==0&&limit2==0)dp[pos]=res;
return res;
}
ll solve(int l,int r){
if(l<0)return 0;
return dfs(l,r,30,1,1);
}
ll gao(){
int l,r;
scanf("%d%d",&l,&r);
return solve(r,r)-2*solve(l-1,r)+solve(l-1,l-1);
}
int main()
{
memset(dp,-1,sizeof(dp));
int l,r;
int q;
scanf("%d",&q);
while(q--){
printf("%lld
",gao());
}
return 0;
}
AC 代码 15ms###
#include<bits/stdc++.h>
#define ll long long
const int N=32;
ll dp[N];
using namespace std;
ll dfs(int l,int r,int pos,bool limit1,bool limit2){
if(pos==-1)return 1;
if(limit1==0&&limit2==0&&dp[pos]!=-1)return dp[pos];
int up1=1,up2=1;
if(limit1)up1=(l>>pos)&1;
if(limit2)up2=(r>>pos)&1;
ll res=0;
for(int i=0;i<=up1;i++){
for(int j=0;j<=up2;j++){
if((i&j)==0)
res+=dfs(l,r,pos-1,limit1&(i==up1),limit2&(j==up2));
}
}
if(limit1==0&&limit2==0)dp[pos]=res;
return res;
}
ll solve(int l,int r){
if(l<0)return 0;
return dfs(l,r,30,1,1);
}
ll gao(){
int l,r;
scanf("%d%d",&l,&r);
return solve(r,r)-2*solve(l-1,r)+solve(l-1,l-1);
}
int main()
{
memset(dp,-1,sizeof(dp));
int l,r;
int q;
scanf("%d",&q);
while(q--){
printf("%lld
",gao());
}
return 0;
}