Sum of Log(2020上海C)
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sum of Log(2020上海C)相关的知识,希望对你有一定的参考价值。
题意:
求 ∑ i = 0 X ∑ j = [ i = 0 ] Y [ i & j = 0 ] ⌊ l o g 2 ( 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就不会产生进位,也就是
⌊
l
o
g
2
(
i
+
j
)
+
1
⌋
\\lfloor log_{2}(i+j)+1\\rfloor
⌊log2(i+j)+1⌋的值就是位数最长的那个数,也就是说i和j中最高位的1是第几位就是
⌊
l
o
g
2
(
i
+
j
)
+
1
⌋
\\lfloor log_{2}(i+j)+1\\rfloor
⌊log2(i+j)+1⌋的值
所以我们对于每一个最高位(也就是枚举
⌊
l
o
g
2
(
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
#else
startTime = clock ();
freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
endTime= 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();
}
以上是关于Sum of Log(2020上海C)的主要内容,如果未能解决你的问题,请参考以下文章
45届ICPC亚洲区域赛(上海)C.Sum of Log(卡常数位dp)
leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和](代码片段
1104 Sum of Number Segments(二刷)