zoukankan      html  css  js  c++  java
  • bzoj 4918: 回文数对

    传送门

    Description

    给定区间[L,R],请统计有多少对整数A,B(L<=A,B<=R)满足A xor B的值在二进制表示下,去掉所有前导0后是回文串

    Input

    第一行包含一个正整数T(1<=T<=100),表示测试数据的组数。
    每组数据包含一行两个整数L,R(0<=L<=R<=10^12),含义如题面所述。

    Output

    对于每组数据输出一行一个整数,即满足条件的整数对个数。
     
     
    反正就是数位dp,从两端往中间跑,记录下大小关系,谁都会写。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    
    ll n,m,T,f[51][16];
    ll min(ll a,ll b){return a<b?a:b;}
    ll work(ll n,ll a,ll b){
        ll MMH=0;
        memset(f,0,sizeof(f));
        f[0][3]=1;
        for (ll i=1;i<=(n>>1);i++)
        for (ll qa=0;qa<2;qa++)
        for (ll qb=0;qb<2;qb++)
        for (ll ha=0;ha<2;ha++)
        for (ll hb=0;hb<2;hb++)
        if ((qa^qb)==(ha^hb)&&(i!=1||qa!=qb)){
            ll QA=(a>>n-i)&1,QB=(b>>n-i)&1;
            ll HA=(a>>i-1)&1,HB=(b>>i-1)&1;
            
            for (ll k=0;k<16;k++){
                ll K=k;
                if (QA<qa&&!(k&8)) continue;
                if (QB<qb&&!(k&4)) continue;
                
                if (QA>qa) K|=8;
                if (QB>qb) K|=4;
                
                if (HA>ha) K|=2;else if (HA<ha) K&=13;
                if (HB>hb) K|=1;else if (HB<hb) K&=14;
                f[i][K]+=f[i-1][k];
            }
        }
        
        if (n&1){
            ll i=n+1>>1;
            for (ll _a=0;_a<2;_a++)
            for (ll _b=0;_b<2;_b++)
            if (n!=1||_a!=_b){
                ll A=(a>>i-1)&1,B=(b>>i-1)&1;
                
                for (ll k=0;k<16;k++){
                    ll K=k;
                    if (A<_a&&!(k&8)) continue;
                    if (B<_b&&!(k&4)) continue;
                    
                    if (A>_a) K|=8;
                    if (B>_b) K|=4;
                    f[i][K]+=f[i-1][k];
                }
            }
        }
        ll i=n+1>>1;
        for (ll k=0;k<16;k++)
        if (((k&8)||(k&2))&&((k&4)||(k&1))) MMH+=f[i][k];
        return MMH;
    }
    ll Mavis(ll a,ll b){
        if (b<0) return 0;
        ll i,j,k,mmh=0;
        for (i=40,j=0,k=0;i;i--){
            j<<=1;k<<=1;j|=(a>>i)&1;k|=(b>>i)&1;
            if (j==k) mmh+=j*work(i,(1ll<<i)-1,(1ll<<i)-1)+work(i,a&((1ll<<i)-1),b&((1ll<<i)-1));else mmh+=k*work(i,(1ll<<i)-1,(1ll<<i)-1)+work(i,(1ll<<i)-1,b&((1ll<<i)-1));
        }
        return mmh+b+1;
    }
    int main(){
        scanf("%lld",&T);
        while(T--){
            scanf("%lld%lld",&n,&m);
            printf("%lld
    ",Mavis(m,m)-2*Mavis(m,n-1)+Mavis(n-1,n-1));
        }
    }
    View Code
  • 相关阅读:
    WPS客户端更新日志留着备用
    C#设置电脑时间帮助类
    分布式数据库拆表拆库的常用策略
    程序员如何对待自己的工作
    java对接申通下单接口示例代码
    电子面单开发流程
    2016年工作总结和计划
    【价值观】大牛们的经典语录
    大话 程序猿 眼里的 接口
    【C#公共帮助类】DateTimeHelper设置电脑本地时间,实际开发很需要
  • 原文地址:https://www.cnblogs.com/Enceladus/p/7124355.html
Copyright © 2011-2022 走看看