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 }

猜你喜欢

转载自www.cnblogs.com/mjtcn/p/9749371.html