zoukankan      html  css  js  c++  java
  • BZOJ3329: Xorequ(二进制数位dp 矩阵快速幂)

    题意

    题目链接

    Sol

    挺套路的一道题

    首先把式子移一下项

    (x oplus 2x = 3x)

    有一件显然的事情:(a oplus b leqslant c)

    又因为$a oplus b + 2(a & b) = c$

    那么$x & 2x = 0$

    也就是说,$x$的二进制表示下不能有相邻位

    第一问直接数位dp即可

    第二问比较interesting,设$f[i]$表示二进制为$i$的方案数,转移时考虑上一位选不选

    如果能选,方案数为$f[i - 2]$

    不选的方案数为$f[i - 1]$

    #include<bits/stdc++.h>
    #define LL long long 
    //#define int long long 
    #define file {freopen("a.in", "r", stdin); freopen("a.out", "w", stdout);}
    using namespace std;
    const int MAXN = 233, mod = 1e9 + 7;
    inline LL read() {
        char c = getchar(); LL x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    LL N;
    struct Matrix {
    	int m[3][3];
    	Matrix() {
    		memset(m, 0, sizeof(m));
    	}
    	Matrix operator * (const Matrix &rhs) const {
    		Matrix ans;
    		for(int k = 1; k <= 2; k++)
    			for(int i = 1; i <= 2; i++)
    				for(int j = 1; j <= 2; j++)
    					(ans.m[i][j] += 1ll * m[i][k] * rhs.m[k][j] % mod) %= mod;
    		return ans;
    	}
    };
    Matrix MatrixPow(Matrix a, LL p) {
    	Matrix base;
    	for(int i = 1; i <= 2; i++) base.m[i][i] = 1;
    	while(p) {
    		if(p & 1) base = base * a;
    		a = a * a; p >>= 1;
    	}
    	return base;
    }
    LL num[MAXN], tot; LL f[MAXN][2];
    LL dfs(int x, bool lim, bool pre) {
    	if(!lim && (~f[x][pre])) return f[x][pre];
    	if(x == 0) return 1;
    	LL ans = 0;
    	if(!pre && (num[x] == 1 || (!lim))) ans += dfs(x - 1, lim, 1);
    	ans += dfs(x - 1, lim && num[x] == 0, 0);
    
    	if(!lim) f[x][pre] = ans;
    	return ans;
    }
    LL dp(LL x) {
    	tot = 0;
    	while(x) num[++tot] = x & 1, x >>= 1;
    	return dfs(tot, 1, 0);
    }	
    main() {
    //	file;
    	memset(f, -1, sizeof(f));
    	int T = read();
    	while(T--) {
    		N = read();
    		printf("%lld
    ", dp(N) - 1);
    		Matrix a;
    		a.m[1][1] = 1; a.m[1][2] = 1;
    		a.m[2][1] = 1; a.m[2][2] = 0;
    		a = MatrixPow(a, N);
    		printf("%d
    ", (a.m[1][1] + a.m[1][2]) % mod);		
    	}
    
        return 0;
    }
    /*
    1
    5
    */
    
    
  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9749495.html
Copyright © 2011-2022 走看看