【ICPC】2020ICPC上海 Sum of Log | 数位dp

赛时(志愿者):这不是裸的数位dp?

赛后(疯狂敲代码):woc,怎么T了..

题目大意:

就是求一下上面式子的和

题目思路:

首先考虑双线程,0~X,0~Y去进行数位dp,与2020牛客多校某题类似

所以很容易可以求出的是 0~X,0~Y中,(i&j) == 0的数量

仔细观察这个式子,因为 i&j == 0,所以每一位必不相同,所以其实就是求对于每一对(i&j) == 0,max( f(i) , f(j) ) 的和,f(x)代表x的二进制最高位

所以就可以在数位dp的每一层中,枚举每一位的贡献,算下它的子树有多少种合法情况,直接将该位的贡献算进去即可

Code:

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define d(x) printf("%lld\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18;
const ll maxn = 4e5+700;
const int mod= 1e9+7;
const int up = 1e9;
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
ll dp[34][2][2];
ll res = 0;
int a[maxn],b[maxn];
ll dfs(int pos,int state,int l1,int l2,int suf){
    if(!pos) return state == 0;
    if(state > 0) return 0;
    if(~dp[pos][l1][l2]) return dp[pos][l1][l2];
    int up1 = l1?a[pos]:1;
    int up2 = l2?b[pos]:1;
    ll temp = 0,ans = 0;
    for(int i=0;i<=up1;i++){
        for(int k=0;k<=up2;k++){
            ll dx = dfs(pos-1,state + (i&k),l1&&i==up1,l2&&k==up2,suf?suf:(i^k));
            if(!suf && (i^k)) temp = (temp + dx)%mod;
            ans = (ans + dx)%mod;
        }
    }
    res = (res + temp*pos)%mod;
    return dp[pos][l1][l2] = ans;
}
ll solve(ll x,ll y){
    int cnt = 0;
    if(x<y) swap(x,y);
    while(x){
        a[++cnt] = x%2;
        x/=2;
    }
    int cot = 0;
    for(int i=1;i<=cnt;i++){
        b[++cot] = y%2;
        y/=2;
    }
    return dfs(cnt,0,1,1,0);
}

int main(){
    int T;scanf("%d",&T);
    while(T--){
        memset(dp,-1,sizeof(dp));
        scanf("%lld%lld",&n,&m);
        res = 0;
        solve(n,m);
        printf("%lld\n",res);
    }
    return 0;
}
/***

***/

猜你喜欢

转载自blog.csdn.net/qq_43857314/article/details/111143132