1194D 1-2-K Game
传送门
镜像
题意:一个魔法宝石可以分成m块普通宝石,询问得到n块宝石的方案数
设F[i]为i块的答案,显然有F[i]=F[i-1]+F[i-m],即最后一块可以分,也可以不分。然后呢,再加上一点细节就可以做出来了(错乱 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 105 #define int long long #define eps 1e-4 #define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); #pragma GCC optimize(2) #define lowbit(x) ((x)&-(x)) #define ull unsigned long long #define db double #define ld long double #define mod 1000000007 struct matrix{ ll m[maxn][maxn]; }; matrix matrix_mul(matrix a,matrix b,ll n){ matrix c{}; for (ll i = 0; i <n ; ++i) { for (ll j = 0; j <n ; ++j) { c.m[i][j]=0; } } for (ll i = 0; i <n ; ++i) { for (ll j = 0; j <n ; ++j) { for (ll k = 0; k <n ; ++k) { c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod; } c.m[i][j]%=mod; } } return c; } matrix slow_pow(ll n,matrix a,ll pow){ matrix b{}; for (ll i = 0; i <n ; ++i) { for (ll j = 0; j <n ; ++j) { if(i==j)b.m[i][j]=1; else b.m[i][j]=0; } } while(pow){ if(pow&1)b=matrix_mul(b,a,n); a=matrix_mul(a,a,n); pow>>=1; } return b; } matrix a{}; signed main(){ IOS int n,m; cin>>n>>m; if(n<m)cout<<1; else{ for (int i = 1; i <m ; ++i) a.m[i][i-1]=1; a.m[0][0]=1; a.m[0][m-1]=1; int tmp=n-m+1; a=slow_pow(m,a,tmp); ll ans=0; for (int k = 0; k <m ; ++k) { ans+=a.m[0][k]; ans%=mod; } cout<<ans%mod; }
return 0; }
|
其实就是用一个m*m的矩阵去加速,否则会T。
矩阵a如代码,乘一个m *1的矩阵,从上向下为F[n-1]~F[n-m]。
552C Vanya and Scales
传送门
镜像
题意:询问w的幂次加减能否得到m
先把m划分成w进制,然后考虑每一位,显然1或0时符合题意,如果是其他情况,我们可以考虑加上某个幂次,如果某一位是w-1,就可以加上该位对应幂次,如果加上之后符合题意,那么他前一位应该是w-2或0或w-1,引申到对连续的w-1去判断,另一种情况是连续的w-2,如果连续的w-2之后有一个w-1,那么也是符合题意的,但是对这两种情况的判定要注意2和3两个特例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 105 #define int long long #define eps 1e-4 #define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); #pragma GCC optimize(2) #define lowbit(x) ((x)&-(x)) #define ull unsigned long long #define db double #define ld long double #define mod 1000000007 vector<int> g,e; signed main(){ IOS int w,m,tmp; cin>>w>>m; tmp=m; int fl=0; while(tmp){ e.push_back(tmp%w); tmp/=w; } for (int j = e.size()-1; j >=0 ; --j) { g.push_back(e[j]); } for (int i = 0; i <g.size() ; ++i) { int aom=0; if(g[i]!=w-1&&g[i]!=w-2&&g[i]!=1&&g[i]!=0){fl=1; break;} if (g[i] == w - 1) { aom=1; if (i != 0 && g[i - 1] != 0 && g[i - 1] != w - 2) { fl = 1; break; } while (i < g.size() && g[i] == w - 1)i++; } int sig=0; while (i < g.size() && g[i] == w - 2){ sig=1; i++; } if(sig)if(i==g.size()||g[i]!=w-1){ if(w!=3&&w!=2)fl=1; break;} if(aom||sig)i--; } if(fl)cout<<"NO"; else cout<<"YES";
return 0; }
|
写了一遍发现顺序反了,就又开了一个vector(二度错乱
1117D Magic Gems
传送门
镜像
题意:总共有n个物品,每次可以取1、2、k个,最后一个取的人获胜,询问赢家。
对于Alice来说,n=0是必输点,那么n+1、n+2、n+k就是必胜点,她可以是Bob无法取,可见,对于每个必输点i,i+1,i+2,i+k都是必胜点。
然后k%3!=0时,显然所有的必败点是3的倍数(包括0)
等于0时,取个6,然后列一下,容易看出来k+1个数构成一个循环,直接按规律判断就好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 1005 #define int long long #define eps 1e-4 #define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); #pragma GCC optimize(2) #define lowbit(x) ((x)&-(x)) #define ull unsigned long long #define db double #define ld long double signed main() { IOS int t; cin>>t; while(t--){ int n,k; cin>>n>>k; if(k%3!=0){ if(n%3!=0)cout<<"Alice"<<endl; else cout<<"Bob"<<endl; }else{ n%=(k+1); if(n<k&&n%3==0)cout<<"Bob"<<endl; else if(n%3!=0||n==k)cout<<"Alice"<<endl; } } return 0; }
|
鱼人节快乐!深潜者万岁!