2020上海ICPC区域赛——C题Sum of Log
   
题目链接:https://ac.nowcoder.com/acm/contest/9925/C
    
    
    题意
   
    给你
    
     
      
       x 
        x
      
      
       
        
        
        
         x
        
       
      
     
    
    和
    
     
      
       y 
        y
      
      
       
        
        
        
         y
        
       
      
     
    
    ,让你求出
    
    
     
      
       ∑ 
i
=
0
x
∑
j
=
[
i
=
=
0
]
y
[
i
        \sum^{x}_{i=0}\sum^{y}_{j=[i==0]}[i
      
      
       
        
        
        
         
          ∑
         
         
          
           
            
             
              
              
              
               
                
                 i
                
                
                 =
                
                
                 0
                
               
              
             
             
              
              
              
               
                
                 x
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         
          ∑
         
         
          
           
            
             
              
              
              
               
                
                 j
                
                
                 =
                
                
                 [
                
                
                 i
                
                
                 =
                
                
                 =
                
                
                 0
                
                
                 ]
                
               
              
             
             
              
              
              
               
                
                 y
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         [
        
        
         i
        
       
      
     
    
    &
    
     
      
       j 
=
0
]
[
l
o
g
2
(
i
+
j
)
+
1
        j=0][log_{2}(i+j)+1
      
      
       
        
        
        
         j
        
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
        
         ]
        
        
         [
        
        
         l
        
        
         o
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 2
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         (
        
        
         i
        
        
        
        
         +
        
        
        
       
       
        
        
        
         j
        
        
         )
        
        
        
        
         +
        
        
        
       
       
        
        
        
         1
        
       
      
     
    
    。
   
    
    
    题解
   
    首先我们要把题目中的公式转换一下,
    
    当
    
     
      
       i 
        i
      
      
       
        
        
        
         i
        
       
      
     
    
    &
    
     
      
       j 
=
=
0
        j==0
      
      
       
        
        
        
         j
        
        
        
        
         =
        
       
       
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
       
      
     
    
    时
    
    
     
      
       ⌊ 
l
o
g
2
(
i
+
j
)
+
1
⌋
        \lfloor log_{2}(i+j)+1 \rfloor
      
      
       
        
        
        
         ⌊
        
        
         l
        
        
         o
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 2
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         (
        
        
         i
        
        
        
        
         +
        
        
        
       
       
        
        
        
         j
        
        
         )
        
        
        
        
         +
        
        
        
       
       
        
        
        
         1
        
        
         ⌋
        
       
      
     
    
    即表示
    
     
      
       i 
        i
      
      
       
        
        
        
         i
        
       
      
     
    
    和
    
     
      
       j 
        j
      
      
       
        
        
        
         j
        
       
      
     
    
    中最高的非
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    二进制位。
    
    eg:
    
     
      
       20 
        20
      
      
       
        
        
        
         2
        
        
         0
        
       
      
     
    
    &
    
     
      
       8 
=
=
0
        8==0
      
      
       
        
        
        
         8
        
        
        
        
         =
        
       
       
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
       
      
     
    
    ,
    
     
      
       20 
        20
      
      
       
        
        
        
         2
        
        
         0
        
       
      
     
    
    的二进制位为
    
     
      
       10100 
        10100
      
      
       
        
        
        
         1
        
        
         0
        
        
         1
        
        
         0
        
        
         0
        
       
      
     
    
    ,
    
     
      
       8 
        8
      
      
       
        
        
        
         8
        
       
      
     
    
    的二进制位为
    
     
      
       01000 
        01000
      
      
       
        
        
        
         0
        
        
         1
        
        
         0
        
        
         0
        
        
         0
        
       
      
     
    
    ,
    
     
      
       ⌊ 
l
o
g
2
(
20
+
8
)
+
1
⌋
=
5
        \lfloor log_{2}(20+8)+1 \rfloor=5
      
      
       
        
        
        
         ⌊
        
        
         l
        
        
         o
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 2
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         (
        
        
         2
        
        
         0
        
        
        
        
         +
        
        
        
       
       
        
        
        
         8
        
        
         )
        
        
        
        
         +
        
        
        
       
       
        
        
        
         1
        
        
         ⌋
        
        
        
        
         =
        
        
        
       
       
        
        
        
         5
        
       
      
     
    
    ,即为
    
     
      
       20 
        20
      
      
       
        
        
        
         2
        
        
         0
        
       
      
     
    
    的最高非
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    二进制位。
    
    因此问题就变的简单了许多。
    
    这次数位
    
     
      
       d 
p
        dp
      
      
       
        
        
        
         d
        
        
         p
        
       
      
     
    
    的状态和
    
     牛客多校第六场的H题
    
    类似。
    
    首先我们需要维护数位
    
     
      
       d 
p
        dp
      
      
       
        
        
        
         d
        
        
         p
        
       
      
     
    
    中固定的一维,即枚举到了第几位。
    
    后面两维也比较套路,即一维维护是否超过
    
     
      
       x 
        x
      
      
       
        
        
        
         x
        
       
      
     
    
    数位上限,一维维护是否超过
    
     
      
       y 
        y
      
      
       
        
        
        
         y
        
       
      
     
    
    数位上限。
    
    还有一维维护是否前一位是否是前导
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    。
    
    剩下的状态就需要我们仔细考虑了。
    
    第一印象肯定是直接维护最高的非
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    二进制位。
    
    但是算一下数据范围发现会超时。
    
    那么我们怎么优化就比较关键了。
    
    因为我们要维护的是最高的非
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    二进制位,
    
    而我们之前已经维护了一维来纪录前导
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    ,每当当前位的前一位是前导
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    且当前位为
    
     
      
       1 
        1
      
      
       
        
        
        
         1
        
       
      
     
    
    时,即表示当前位会对后面所有合法数的个数产生贡献,因此这个状态已经足够我们维护答案了。
    
    状态:
    
    
     
      
       d 
p
[
p
o
s
]
[
s
x
]
[
s
y
]
[
l
e
a
d
]
        dp[pos][sx][sy][lead]
      
      
       
        
        
        
         d
        
        
         p
        
        
         [
        
        
         p
        
        
         o
        
        
         s
        
        
         ]
        
        
         [
        
        
         s
        
        
         x
        
        
         ]
        
        
         [
        
        
         s
        
        
         y
        
        
         ]
        
        
         [
        
        
         l
        
        
         e
        
        
         a
        
        
         d
        
        
         ]
        
       
      
     
    
    表示当前位为
    
     
      
       p 
o
s
        pos
      
      
       
        
        
        
         p
        
        
         o
        
        
         s
        
       
      
     
    
    ,sx表示是否已经超过
    
     
      
       x 
        x
      
      
       
        
        
        
         x
        
       
      
     
    
    数位上限,sy表示是否已经超过
    
     
      
       y 
        y
      
      
       
        
        
        
         y
        
       
      
     
    
    数位上限,
    
     
      
       l 
e
a
d
        lead
      
      
       
        
        
        
         l
        
        
         e
        
        
         a
        
        
         d
        
       
      
     
    
    表示前一位是否为前导
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    。
    
    剩下的过程算是数位
    
     
      
       d 
p
        dp
      
      
       
        
        
        
         d
        
        
         p
        
       
      
     
    
    的套路,枚举x的数位和
    
     
      
       y 
        y
      
      
       
        
        
        
         y
        
       
      
     
    
    的数位也算是牛客多校的套路。
   
    
    
    代码
   
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int mod = 1e9+7;
int a[40],b[40];
ll dp[40][2][2][2];
int len;
ll dfs(int pos,int sx,int sy,int lead){
    if(pos==-1) return 1;
    if(dp[pos][sx][sy][lead]!=-1) return dp[pos][sx][sy][lead];
    ll ans=0;
    int up1=(sx?a[pos]:1);
    int up2=(sy?b[pos]:1);
    rp(i,0,up1){
        rp(j,0,up2){
            if(i&j) continue;
            ll num=1;
            if(lead&&(i||j)) num=pos+1;
            ans=(ans+1ll*dfs(pos-1,sx&&i==up1,sy&&j==up2,lead&&!i&&!j)*num%mod)%mod;
        }
    }
    return dp[pos][sx][sy][lead]=ans;
}
void solve(){
    int x=read(),y=read();
    mst(dp,-1);
    len=0;
    while(x||y){
        a[len]=(x&1);
        b[len]=(y&1);
        y>>=1;
        x>>=1;
        len++; 
    }
    cout<<(dfs(len-1,1,1,1)-1+mod)%mod<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();
    int T=read();
    while(T--) solve();
    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}
 
