3329: Xorequ
3329: Xorequ
https://www.lydsy.com/JudgeOnline/problem.php?id=3329
分析:
因为a+b = a^b + ((a&b)<<1)
所以(x&(2x))<<1是0,就是没有相邻的1。然后计算多少x满足没有相邻的1。
第一问:数位dp一下,dp[i][j]到第i位,上一个数是j的方案数。
第二问:一共n位数,只有第n位为1,所以这n位没有限制,f[i]表示到第i位,的方案数,f[i]=f[i-1]+f[i-2]。看第i位是不是1。
代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #define fi(s) freopen(s,"r",stdin); 12 #define fo(s) freopen(s,"w",stdout); 13 using namespace std; 14 typedef long long LL; 15 16 inline LL read() { 17 LL x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 18 for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 19 } 20 21 const int mod = 1e9 + 7; 22 23 LL dp[100][2], num[100]; 24 25 struct Matrix{ 26 int a[2][2]; 27 void Clear() { memset(a, 0, sizeof(a)); } 28 void init() { a[0][0] = a[0][1] = a[1][0] = 1; } 29 Matrix operator * (const Matrix &A) const { 30 Matrix C; C.Clear(); 31 for (int k=0; k<2; ++k) 32 for (int i=0; i<2; ++i) 33 for (int j=0; j<2; ++j) 34 C.a[i][j] = (C.a[i][j] + 1ll * a[i][k] * A.a[k][j]) % mod; 35 return C; 36 } 37 }; 38 LL dfs(int x,int last,bool lim) { 39 if (!x) return 1; 40 if (!lim && dp[x][last]) return dp[x][last]; 41 int u = lim ? num[x] : 1; // u = lim ? num[x] : 0 !!! 42 LL res = 0; 43 for (int i=0; i<=u; ++i) 44 if (!last || !i) res += dfs(x - 1, i, lim && i==u); 45 if (!lim) dp[x][last] = res; 46 return res; 47 } 48 LL Calc1(LL n) { 49 int tot = 0; 50 while (n) { 51 num[++tot] = n & 1; 52 n >>= 1; 53 } 54 return dfs(tot, 0, 1) - 1; 55 } 56 LL Calc2(LL n) { 57 Matrix A; A.Clear(); A.init(); 58 Matrix res; res.Clear(); res.a[0][0] = res.a[1][1] = 1; 59 while (n) { 60 if (n & 1) res = res * A; 61 A = A * A; 62 n >>= 1; 63 } 64 return (res.a[0][0] + res.a[0][1]) % mod; 65 } 66 int main() { 67 int T = read(); 68 while (T--) { 69 LL n = read(); 70 printf("%lld\n%lld\n", Calc1(n), Calc2(n)); 71 } 72 return 0; 73 }