• 启智树提高组day4T3 T3(t3.cpp,1s,512MB)


    启智树提高组day4T3 T3(t3.cpp,1s,512MB)

    题面描述

     输入格式

    输出格式

    样例输入

    样例输出

    数据范围

    题解

     task1

    暴力dfs

    10分

    Code

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #define IL inline
    11 #define re register
    12 #define LL long long
    13 #define ULL unsigned long long
    14 using namespace std;
    15 //1e1
    16 template<class T>inline void read(T&x)
    17 {
    18     char ch=getchar();
    19     while(!isdigit(ch))ch=getchar();
    20     x=ch-'0';ch=getchar();
    21     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    22 }
    23 int G[55];
    24 template<class T>inline void write(T x)
    25 
    26 {
    27     int g=0;
    28     do{G[++g]=x%10;x/=10;}while(x);
    29     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('
    ');
    30 }
    31 const ULL M = 1e9+7;
    32 ULL range[64]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,9223372036854775808};
    33 ULL dfs(ULL num,ULL now)
    34 {
    35     if(num==0) return 1;
    36     ULL ans=0;
    37     for(int i=now;i>=0;i--)
    38     {
    39         if(range[i]>num) continue;
    40 //        cout<<"dfs"<<i<<endl;
    41         ans+=dfs(num-range[i],i);
    42     }
    43     return ans%M;
    44 }
    45 
    46 ULL n,T;
    47 int main()
    48 {
    49     cin>>T;
    50     while(T--)
    51     {
    52         read(n);
    53         write(dfs(n,64)%M);
    54     }
    55     
    56     return 0;
    57 }
    View Code

    task2

    加入记忆化(先用map)

    Code

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #define IL inline
    11 #define re register
    12 #define LL long long
    13 #define ULL unsigned long long
    14 using namespace std;
    15 //1e5
    16 template<class T>inline void read(T&x)
    17 {
    18     char ch=getchar();
    19     while(!isdigit(ch))ch=getchar();
    20     x=ch-'0';ch=getchar();
    21     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    22 }
    23 int G[55];
    24 template<class T>inline void write(T x)
    25 {
    26     int g=0;
    27     do{G[++g]=x%10;x/=10;}while(x);
    28     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('
    ');
    29 }
    30 const ULL M = 1e9+7;
    31 ULL range[64]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,9223372036854775808};
    32 struct Pair{
    33     ULL a,b;
    34     
    35 };
    36 bool operator<(Pair y,Pair x){
    37     return (y.a==x.a)?y.b<x.b:y.a<x.a; 
    38 }
    39 map<Pair,ULL>his; 
    40 ULL dfs(ULL num,ULL now)
    41 {
    42     if(num==0) return 1;
    43     if(his.find({num,now})!=his.end()) return his[{num,now}];
    44     ULL ans=0;
    45     for(int i=now;i>=0;i--)
    46     {
    47         if(range[i]>num) continue;
    48 //        cout<<"dfs"<<i<<endl;
    49         ans+=dfs(num-range[i],i);
    50     }
    51     return his[{num,now}]=ans%M;
    52 }
    53 
    54 ULL n,T;
    55 int main()
    56 {
    57     cin>>T;
    58     while(T--)
    59     {
    60         read(n);
    61         write(dfs(n,64)%M);
    62     }
    63     return 0;
    64 }
    View Code

    task3

    不幸的是,刚刚两种方法都只有10分!!!

    通过用task2打表发现

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #define IL inline
    11 #define re register
    12 #define LL long long
    13 #define ULL unsigned long long
    14 using namespace std;
    15 //1e5
    16 template<class T>inline void read(T&x)
    17 {
    18     char ch=getchar();
    19     while(!isdigit(ch))ch=getchar();
    20     x=ch-'0';ch=getchar();
    21     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    22 }
    23 int G[55];
    24 template<class T>inline void write(T x)
    25 {
    26     int g=0;
    27     do{G[++g]=x%10;x/=10;}while(x);
    28     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('
    ');
    29 }
    30 const ULL M = 1e9+7;
    31 ULL range[64]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904,9223372036854775808};
    32 struct Pair{
    33     ULL a,b;
    34     
    35 };
    36 bool operator<(Pair y,Pair x){
    37     return (y.a==x.a)?y.b<x.b:y.a<x.a; 
    38 }
    39 map<Pair,ULL>his; 
    40 ULL dfs(ULL num,ULL now)
    41 {
    42     if(num==0) return 1;
    43     if(his.find({num,now})!=his.end()) return his[{num,now}];
    44     ULL ans=0;
    45     for(int i=now;i>=0;i--)
    46     {
    47         if(range[i]>num) continue;
    48 //        cout<<"dfs"<<i<<endl;
    49         ans+=dfs(num-range[i],i);
    50     }
    51     return his[{num,now}]=ans%M;
    52 }
    53 
    54 ULL n,T,t;
    55 int main()
    56 {
    57     cin>>T;
    58     for(int i=1;i<=T;i++) cout<<i<<"	"<<dfs(i,64)<<"	"<<dfs(i,64)-n<<endl,n=dfs(i,64);
    59     return 0;
    60 }
    记忆化打表
    1. 第i个和第i-1个的值相同(当i>1且i为奇数的时候)
    2. f[i]=f[i/2]+f[i-1]

    差分一下就可以发现规律

    http://oeis.org/search?q=1%2C2%2C4%2C6%2C10%2C14%2C20%2C26&sort=&language=english&go=Search

    在OEIS上也能搜到

    http://oeis.org/A000123

    但是上面也只有这个式子

    这里就可以用记忆化+打表,大概可以做出10^9

    Code

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #define IL inline
    11 #define re register
    12 #define LL long long
    13 #define ULL unsigned long long
    14 using namespace std;
    15 //1e5
    16 template<class T>inline void read(T&x)
    17 {
    18     char ch=getchar();
    19     while(!isdigit(ch))ch=getchar();
    20     x=ch-'0';ch=getchar();
    21     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    22 }
    23 int G[55];
    24 template<class T>inline void write(T x)
    25 {
    26     int g=0;
    27     do{G[++g]=x%10;x/=10;}while(x);
    28     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('
    ');
    29 }
    30 const ULL M = 1e9+7;
    31 //ULL range[63]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,2305843009213693952,4611686018427387904};
    32 struct Pair{
    33     ULL a,b;
    34     
    35 };
    36 bool operator<(Pair y,Pair x){
    37     return (y.a==x.a)?y.b<x.b:y.a<x.a; 
    38 }
    39 map<ULL,ULL>his; 
    40 ULL dfs(ULL num)
    41 {
    42     if(num==0) return 1;
    43     if(num&1&&num>1) return dfs(num-1);
    44     if(his.find(num)!=his.end()) return his[num];
    45     ULL ans=0;
    46     ans=dfs(num/2)+dfs(num-1);
    47     return his[num]=ans%M;
    48 }
    49 
    50 ULL n,T;
    51 int main()
    52 {
    53     cin>>T;
    54     his[1]=1;
    55     his[2]=2;
    56     while(T--)
    57     {
    58         read(n);
    59         write(dfs(n)%M);
    60     }
    61     return 0;
    62 }
    记忆化打表

    Std

    Code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 using ll=long long;
     4 const ll mod=1e9+7;
     5 int T;
     6 ll n,f[70][70],g[70][70],S[70][70],S1[70][70];
     7 ll po(ll a,ll b){ll r=1;for(;b;b/=2,a=a*a%mod)if(b&1)r=r*a%mod;return r;}
     8 ll solve(int x,int k){
     9     if(!(n>>x))return k?0:1;
    10     if(f[x][k]>-1e18)return f[x][k];
    11     ll res=0,t=1;
    12     for(int i=0;i<=k+1;i++)(res+=g[k][i]*t)%=mod,(t*=((n>>x)+1)%mod)%=mod;
    13     (res*=solve(x+1,0))%=mod;t=1;
    14     for(int i=0;i<=k+1;i++)(res-=solve(x+1,i)*g[k][i]%mod*t)%=mod,(t*=2)%=mod;
    15     return f[x][k]=res;
    16 }
    17 int main(){
    18     scanf("%d",&T);
    19     for(int i=0;i<70;i++){
    20         S[i][0]=S1[i][0]=!i;
    21         for(int j=1;j<=i;j++)
    22             S[i][j]=(S[i-1][j-1]+j*S[i-1][j])%mod,
    23             S1[i][j]=(S1[i-1][j-1]+(i-1)*S1[i-1][j])%mod;
    24     }
    25     for(int k=0;k<=64;k++)
    26         for(int j=0;j<=k;j++){
    27             ll cf=S[k][j]*po(j+1,mod-2)%mod;
    28             for(int i=0;i<=j+1;i++)(g[k][i]+=cf*S1[j+1][i]*(j+i&1?1:-1))%=mod;
    29         }
    30     while(T--){
    31         scanf("%lld",&n);
    32         memset(f,192,sizeof f);
    33         printf("%lld
    ",(solve(1,0)+mod)%mod);
    34 
    35     }
    36     return 0;
    37 }

    小结

    别等黄花菜都凉了才——

    别等服务器都炸了才交代码

  • 相关阅读:
    HNCU 1746: 算法4-1,4-3:定位子串
    HNCU 1330: 算法3-1:八进制数
    HNCU 1741: 算法3-2:行编辑程序
    51NOD 1073 约瑟夫环
    约瑟夫问题
    HNCU1325: 算法2-3~2-6:Big Bang(静态链表)
    指针知识复习
    html----学完总结
    html7---转载---为何img,input等内联元素可以设置高度与宽度
    html6---转载---块级元素与行内元素
  • 原文地址:https://www.cnblogs.com/send-off-a-friend/p/13534477.html
Copyright © 2020-2023  润新知