# BZOJ3329 Xorequ 数位dp

noi第一ysy大佬题解。

 1 #include<cstring>
2 #include<cmath>
3 #include<algorithm>
4 #include<cstdio>
5 #include<iostream>
6
7 #define mod 1000000007
8 #define ll long long
9 using namespace std;
11 {
12     ll x=0,f=1;char ch=getchar();
13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
15     return x*f;
16 }
17
18 ll n;
19 ll f[64][2][2],bin[67];
20 ll a[3][3],b[3][3],ans[3][3],t[3][3],g[3];
21
22 void mul(ll b)
23 {
24     ans[1][1]=1,ans[2][2]=1;ans[1][2]=ans[2][1]=0;
25     while(b)
26     {
27         if(b&1)
28         {
29             memset(t,0,sizeof(t));
30             for (int i=1;i<=2;i++)
31                 for (int j=1;j<=2;j++)
32                     for (int k=1;k<=2;k++)
33                         (t[i][j]+=ans[i][k]*a[k][j])%=mod;
34             for (int i=1;i<=2;i++)
35                 for (int j=1;j<=2;j++)
36                     ans[i][j]=t[i][j];
37         }
38         memset(t,0,sizeof(t));
39         for (int i=1;i<=2;i++)
40             for (int j=1;j<=2;j++)
41                 for (int k=1;k<=2;k++)
42                     (t[i][j]+=a[i][k]*a[k][j])%=mod;
43         for (int i=1;i<=2;i++)
44             for (int j=1;j<=2;j++)
45                 a[i][j]=t[i][j];
46         b>>=1;
47     }
48 }
49 int main()
50 {
52     bin[0]=1;
53     for (ll i=1;i<=63;i++)
54         bin[i]=bin[i-1]<<1;
55     while(T--)
56     {
57         memset(f,0,sizeof(f));
59         ll x=0;while(bin[x]<=n)x++;x--;
60         f[x][1][1]=1,f[x][0][0]=1;
61         for (ll i=x-1;i>=0;i--)
62         {
63             if(n&bin[i])
64             {
65                 f[i][1][1]=f[i+1][0][1];
66                 f[i][1][0]=f[i+1][0][0];
67                 f[i][0][0]=f[i+1][1][1]+f[i+1][1][0]+f[i+1][0][1]+f[i+1][0][0];
68             }
69             else
70             {
71                 f[i][1][0]=f[i+1][0][0];
72                 f[i][0][0]=f[i+1][1][0]+f[i+1][0][0];
73                 f[i][0][1]=f[i+1][1][1]+f[i+1][0][1];
74             }
75         }
76         printf("%lld\n",f[0][0][0]+f[0][0][1]+f[0][1][0]+f[0][1][1]-1);
77         g[1]=2,g[2]=3;
78         if(n<=2)
79         {
80             printf("%lld\n",g[n]);
81             continue;
82         }
83         a[1][1]=0,a[1][2]=1,a[2][1]=1,a[2][2]=1;
84         mul(n-2);
85         printf("%lld\n",(ans[1][2]*2+ans[2][2]*3)%mod);
86     }
87 }

posted @ 2018-01-22 00:14  Kaiser-  阅读(164)  评论(0编辑  收藏  举报