Sum of Log
题意:
求∑i=0X∑j=[i=0]Y[i&j=0]⌊log2(i+j)+1⌋\sum_{i=0}^{X}\sum_{j=[i=0]}^{Y}[i\&j=0]\lfloor log_{2}(i+j)+1\rfloor∑i=0X∑j=[i=0]Y[i&j=0]⌊log2(i+j)+1⌋
题解:
数位dp
如果式子想有意义,i&j就要等于0,也就是i和j的任何一位都不能同时为1,那么i+j就不会产生进位,也就是⌊log2(i+j)+1⌋\lfloor log_{2}(i+j)+1\rfloor⌊log2(i+j)+1⌋的值就是位数最长的那个数,也就是说i和j中最高位的1是第几位就是⌊log2(i+j)+1⌋\lfloor log_{2}(i+j)+1\rfloor⌊log2(i+j)+1⌋的值
所以我们对于每一个最高位(也就是枚举⌊log2(i+j)+1⌋\lfloor log_{2}(i+j)+1\rfloor⌊log2(i+j)+1⌋的值),取求i&j==0的个数有多少个,相乘就是答案
代码中的num表示当前位是否是最高位(0表示当前是最高位,1表示不是)
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...);
}
template <typename T> inline void write(T x)
{if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#elsestartTime = clock ();freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int mod=1e9+7;
const int maxn=50;
int lg[maxn];
int a[40],b[40];
ll dp[40][2][2];
ll res=0;
ll dfs(int len,int flag1,int flag2,bool num){if(!len)return 1;if(dp[len][flag1][flag2]!=-1)return dp[len][flag1][flag2]%mod;int up1=flag1?a[len]:1;int up2=flag2?b[len]:1;ll ans=0,cnt=0;for(int i=0;i<=up1;i++){for(int j=0;j<=up2;j++){if((i&&j))continue;int tmp=dfs(len-1,flag1&&(i==up1),flag2&&(j==up2),num||i||j)%mod;ans=(ans+tmp)%mod; if(num==0&&(i|j))cnt=(cnt+tmp)%mod;}}res=(res+cnt*len)%mod;return dp[len][flag1][flag2]=ans%mod;
}
ll solve(ll x,ll y){res=0;memset(dp,-1,sizeof(dp));memset(a,0,sizeof(a));memset(b,0,sizeof(b));int cnt1=0;while(x){a[++cnt1]=x%2;x>>=1;}int cnt2=0;while(y){b[++cnt2]=y%2;y>>=1;}ll ans=dfs(max(cnt1,cnt2),1,1,0);return res%mod;
}
int main()
{rd_test();lg[0]=-1;for(int i=1;i<=40;i++)lg[i]=lg[i>>1]+1;int t;read(t);while(t--){ll x,y;read(x,y);cout<<solve(x,y)<<endl;}return 0;//Time_test();
}