zoukankan      html  css  js  c++  java
  • bzoj3329 Xorequ

    3329: Xorequ

    Time Limit: 1 Sec  Memory Limit: 256 MB
    Submit: 1427  Solved: 601
    [Submit][Status][Discuss]

    Description

    Input

    第一行一个正整数,表示数据组数据 ,接下来T行
    每行一个正整数N

    Output

    2*T行
    第2*i-1行表示第i个数据中问题一的解,

    第2*i行表示第i个数据中问题二的解,

    Sample Input

    1
    1

    Sample Output

    1
    2

    HINT

    x=1与x=2都是原方程的根,注意第一个问题的解
    不要mod 10^9+7

    1<=N<=10^18 
    1<=T<=1000

    Source

    By Wcmg

    分析:好题.

       第一问考察对二进制数的运算的一些性质的掌握.

       因为a xor b = c等价于 a xor c = b,所以方程可以变形为x xor 2x = 3x. 

       既然涉及到xor运算,就要以二进制的视角去研究这些数. 2x可以看作x左移一位得到. 

       观察发现3x = x + 2x,那么x xor 2x = x + 2x.

       xor又叫二进制运算中不进位的加法.不能进位,说明没有1在一起,而2x是由x左移得到的,所以可以得到结论:x不能有连续的1存在.可以用数位dp解决.

       第二问就考验找规律能力了. 这个数可能有10^18位,数位dp都处理不了了......也没有别的方法了,只能找规律. 找几个小点的n,很容易就能发现答案就是斐波那契数列的第n+2项,矩阵快速幂就能搞定.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    const ll mod = 1e9 + 7;
    ll T,n,ans,num[1100],tot,f[1100][2];
    
    struct node
    {
        ll x[3][3];
        void clear()
        {
            memset(x,0,sizeof(x));
        }
    }a,b,c;
    
    void operator *= (node &p,node &q)
    {
        c.clear();
        for (int i = 1; i <= 2; i++)
            for (int j = 1; j <= 2; j++)
                for (int k = 1; k <= 2; k++)
                    c.x[i][j] = (c.x[i][j] + p.x[i][k] * q.x[k][j] % mod) % mod;
        p = c;
    }
    
    ll dfs(ll len,ll if1,bool limit)
    {
        if (len == 0)
            return 1;
        if (!limit && ~f[len][if1])
            return f[len][if1];
        ll shangxian = (limit ? num[len] : 1),cnt = 0;
        for (ll i = 0; i <= shangxian; i++)
        {
            if (i == 0 || if1 == 0)
            cnt += dfs(len - 1,i,(limit && i == shangxian));
        }
        if (limit)
            return cnt;
        else
            return f[len][if1] = cnt;
    }
    
    ll solve1()
    {
        tot = 0;
        ll x = n;
        while (x)
        {
            num[++tot] = x % 2;
            x /= 2;
        }
        return dfs(tot,0,1);
    }
    
    void init()
    {
        tot = 0;
        memset(num,0,sizeof(num));
        memset(f,-1,sizeof(f));
        ans = 0;
    }
    
    void qpow(ll c)
    {
        while (c)
        {
            if (c & 1)
                a *= b;
            b *= b;
            c >>= 1;
        }
    }
    
    void solve2()
    {
        a.clear();
        b.clear();
        a.x[1][1] = 1;
        a.x[2][2] = 1;
        b.x[1][1] = 1;
        b.x[1][2] = 1;
        b.x[2][1] = 1;
        qpow(n + 1);
        ans = a.x[1][1];
    }
    
    int main()
    {
        scanf("%lld",&T);
        while (T--)
        {
            init();
            scanf("%lld",&n);
            printf("%lld
    ",solve1() - 1);
            solve2();
            printf("%lld
    ",ans);
        }
    
        return 0;
    }

     

  • 相关阅读:
    BottomNavigationView3个项以上不显示文字的问题
    ViewPager中height=wrap_content无效,ScrollView里边用ListView显示不全解决办法
    Gson解析
    Parcelable Android SDK提供,基于内存,读写高于硬盘
    Serializable序列化 && 坑
    OpenStack中添加Floating IP
    Hadoop
    Redis
    ELK
    OpenStack
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8462234.html
Copyright © 2011-2022 走看看