启智树提高组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('\n'); 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 }
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('\n'); 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 }
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('\n'); 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<<"\t"<<dfs(i,64)<<"\t"<<dfs(i,64)-n<<endl,n=dfs(i,64); 59 return 0; 60 }
- 第i个和第i-1个的值相同(当i>1且i为奇数的时候)
- 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上也能搜到
但是上面也只有这个式子
这里就可以用记忆化+打表,大概可以做出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('\n'); 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\n",(solve(1,0)+mod)%mod); 34 35 } 36 return 0; 37 }
小结
别等黄花菜都凉了才——
别等服务器都炸了才交代码