zoukankan      html  css  js  c++  java
  • bzoj3329 Xorequ

    思路

    一道比较经典的题。
    (xotimes 3x=2x)等价于(x otimes 2x=3x)
    异或其实就是不进位的加法。因为(x + 2x=3x),所以只要满足(x+2x)在二进制上没有进位即可。很容易发现其实就是要求(x)的二进制位置上没有相邻的两个(1)
    对于第一问,很裸的数位(dp)
    对于第二问,我们用(f[i])表示在二进制表示下,(x)的前(i)位中没有相邻的两个(1)的方案数。如果第(i)位填(0),那么只要前(i-1)位没有相邻的(1)就行了。所以(f[i]+=f[i-1]),如果第(i)位填(1)。那么第(i-1)位必须是(0),所以前(i - 2) 位没有相邻的(1)就行了,所以(f[i]+=f[i-1])。所以(f[i]=f[i-1]+f[i-2]),就是菲波那切数列了。矩阵快速幂优化一下子就(OK)了。

    代码

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    ll read() {
    	ll x=0,f=1;char c=getchar();
    	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;
    }
    namespace BF1 {
    	int a[100],tot;
    	ll f[100][2][2];
    	ll dfs(int pos,int limit,int lst) {
    		if(pos == 0) return 1;
    		if(f[pos][limit][lst]) return f[pos][limit][lst];
    		if(limit) {
    			if(a[pos] == 0) f[pos][limit][lst] += dfs(pos - 1,1,0);
    			else {
    				f[pos][limit][lst] += dfs(pos - 1,0,0);
    				if(!lst) f[pos][limit][lst] += dfs(pos - 1,1,1);
    			}
    		}
    		else {
    			f[pos][limit][lst] += dfs(pos - 1,0,0);
    			if(!lst) f[pos][limit][lst] += dfs(pos - 1,0,1);
    		}
    		return f[pos][limit][lst];
    	}
    	void solve(ll x) {
    		tot = 0;
    		while(x) {
    			a[++tot] = x & 1;
    			x >>= 1;
    		}
    		memset(f,0,sizeof(f));
    		printf("%lld
    ",dfs(tot,1,0) - 1);
    	}
    }
    namespace BF2 {
    
    	struct node {
    		ll a[10][10];
    		int n,m;
    		node() {
    			memset(a,0,sizeof(a));n = 0,m = 0;
    		}
    		node(int x,int y) {
    			n = x,m = y;
    			memset(a,0,sizeof(a));
    		}
    		node(int nn) {
    			n = m = nn;
    			memset(a,0,sizeof(a));
    			for(int i = 1;i <= nn;++i) a[i][i] = 1;
    		}
    	};
    	node operator * (const node &x,const node &y) {
    		int n = x.n,m = y.m,K = x.m;
    		node ret(n,m);
    		for(int k = 1;k <= K;++k)
    			for(int i = 1;i <= n;++i)
    				for(int j = 1;j <= m;++j)
    					ret.a[i][j] += x.a[i][k] * y.a[k][j] % mod,ret.a[i][j] %= mod;
    		return ret;
    	}
    	node operator ^ (node x,ll y) {
    		node ret(x.n);
    		for(;y;y >>= 1,x = x * x)
    			if(y & 1) ret = x * ret;
    		return ret;
    	}
    	void solve(ll n) {
    		node A(1,2);
    		A.a[1][1] = A.a[1][2] = 1;
    		node C(2,2);
    		C.a[1][1] = C.a[1][2] = C.a[2][1] = 1;
    		A = A * (C ^ n);
    		printf("%lld
    ",A.a[1][1]);
    	}
    }
    int main() {
    	int T = read();
    	while(T--) {
    		ll n = read();
    		BF1::solve(n);
    		BF2::solve(n);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/wxyww/p/bzoj3329.html
Copyright © 2011-2022 走看看