卧薪尝胆,厚积薄发。
Xorequ
Date: Thu Sep 06 09:32:59 CST 2018 In Category: NoCategory

Description:

求小于等于 $n$ 和 $2^n$ 的正整数中,有多少是 $x\text{ xor }3x=2x$ 的解。
$1\le n\le 10^{18},1\le T \le 1000$

Solution:

移项,把 $3x$ 拆开,得 $(x+2x)=x\text{ xor }2x$ ,即 $(x+(x<<1))=x\text{ xor }(x<<1)$ ,也就是二进制下不含相邻一的数字的个数,二进制数位 $DP$ ,记 $f[i][0/1]$ 表示到了第 $i$ 位选 $0/1$ 的方案数,转移为 $f[i][0]=f[i-1][0]+f[i-1][1],f[i][1]=f[i-1][0]$ 。
然后从高到低枚举每一位,如果这一位是一,就加上 $f[i][0]$ ,注意原数中如果有连续相同的两位就 $break$ ,因为后面的都不合法。
然后对于第二问,打表发现是一个斐波那契数列,矩阵快速幂即可。原因是 $f[i][0]=f[i-1][0]+f[i-1][1]=f[i-1][0]+f[i-2][0]$ 。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
ll n;
#define MAXL 70
ll f[MAXL][2];
#define MOD 1000000007
struct matrix
{
ll m[3][3];
matrix(){memset(m,0,sizeof(m));}
friend matrix operator * (matrix a,matrix b)
{
matrix c;
for(int i = 1;i <= 2;++i)
for(int j = 1;j <= 2;++j)
for(int k = 1;k <= 2;++k)
c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j] % MOD) % MOD;
return c;
}
friend matrix operator ^ (matrix a,ll b)
{
matrix res = a;--b;
while(b > 0)
{
if(b & 1)res = res * a;
a = a * a;
b = b >> 1;
}
return res;
}
}s;
void work()
{
scanf("%lld",&n);
memset(f,0,sizeof(f));
f[0][0] = f[0][1] = 1;
for(int i = 1;i <= 62;++i)
{
f[i][0] = f[i - 1][0] + f[i - 1][1];
f[i][1] = f[i - 1][0];
}
ll ans = 0;
for(ll i = 62;i >= 0;--i)
{
if((n & (1ll << i)))ans += f[i][0];
if((n & (1ll << i)) && (n & (1ll << (i + 1))))
{
--ans;
break;
}
}
printf("%lld\n",ans);
s.m[1][1] = s.m[1][2] = s.m[2][1] = 1;s.m[2][2] = 0;
s = s ^ (n + 1);
printf("%lld\n",s.m[1][1]);
return;
}
int main()
{
int testcases;
scanf("%d",&testcases);
while(testcases--)work();
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡