zoukankan      html  css  js  c++  java
  • BZOJ 3329

    Solution

    发现 $x xor   2x = 3x$ 仅当 $x$ 的二进制中没有相邻的 $1$

    对于第一个问题就可以进行数位DP 了。

    但是对于第二个问题, 我们只能通过递推 打表 来算出答案了。

    推公式 打表 可知, 这是一个斐波那契数列, $a_0 = 1, a_1 = 2, a_2 = 3$.... 

    通过矩阵快速幂优化递推就可以过啦

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 #define ll long long
     6 using namespace std;
     7  
     8 const int mod = 1e9 + 7;
     9  
    10 const int N = 70;
    11  
    12 int T, a[100];
    13 ll sum[N][2], n;
    14  
    15 struct matrix {
    16     ll s[4][4];
    17     matrix operator * (const matrix &b) const {
    18         matrix re;
    19         memset(re.s, 0, sizeof(re.s));
    20         for(int i = 1; i <= 2; ++i)
    21             for(int k = 1; k <= 2; ++k)
    22                 for(int j = 1; j <= 2; ++j)
    23                     re.s[i][j] = (re.s[i][j] + s[i][k] * b.s[k][j]) % mod;
    24         return re;
    25     }
    26 }ans, st;
    27  
    28 struct node {
    29     int id;
    30     ll in, out1, out2;
    31 }b[1005];
    32  
    33 ll read() {
    34     ll X = 0 , p = 1; char c = getchar();
    35     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    36     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    37     return X * p;
    38 }
    39  
    40 ll dfs(int pos, int pre, int lim, int lead) {
    41     if(!pos) return lead == 0;
    42     if(!lim && !lead && sum[pos][pre] != -1)
    43         return sum[pos][pre];
    44     int up = lim ? a[pos] : 1;
    45     ll tmp = 0;
    46     for(int i = 0; i <= up; ++i) {
    47         if(pre && i)
    48             continue;
    49         tmp += dfs(pos - 1, i, lim && a[pos] == i, lead && i == 0);
    50     }
    51     if(!lim && !lead)
    52         sum[pos][pre] = tmp;
    53     return tmp;
    54 }
    55  
    56 ll work(ll x) {
    57     int len = 0;
    58     while(x) a[++len] = x % 2, x /= 2;
    59     return dfs(len , 0, true, true);
    60 }
    61  
    62 inline bool cmp1(const node &A, const node &B ) {
    63     return A.in < B.in;
    64 }
    65  
    66 inline bool cmp2(const node &A, const node &B) {
    67     return A.id < B.id;
    68 }
    69  
    70 void print(ll x) {
    71     sort(b + 1, b + 1 + T, cmp1);
    72     memset(sum, -1, sizeof(sum));
    73     memset(st.s, 0, sizeof(st.s));
    74     memset(ans.s, 0, sizeof(ans.s));
    75     st.s[1][2] = st.s[2][1] = st.s[2][2] = 1;
    76     ans.s[1][1] = 1;
    77     ans.s[1][2] = 2;
    78     printf("%lld
    ", work(x));
    79     for(; x; x >>= 1, st = st * st)
    80         if(x & 1) ans = ans * st;
    81     printf("%lld
    ", (ans.s[1][1] % mod + mod) % mod);
    82 }
    83  
    84 int main()
    85 {
    86     T = rd;
    87     for(; T; T--) print(rd);
    88 }
    89 
    View Code
  • 相关阅读:
    vue学习之router
    vue学习之组件
    xshell操作
    Webstorm快捷操作
    javascript判断节点是否在dom
    影子节点 shadowDOM
    虚拟节点操作——DocumentFragment
    理解浏览器的历史记录
    浏览器渲染
    web请求流程
  • 原文地址:https://www.cnblogs.com/cychester/p/9649798.html
Copyright © 2011-2022 走看看