《2021牛客寒假算法基础集训营1》补题
A:感觉这题蛮难的,没想到这么多人过。
比赛的时候推dp推了挺久没推出来。
dp[i]表示i长度的包含u,s的串的方案数。
考虑转移:
1:前i个长度已经包含了u,s,那么随便新加入一个就行,即dp[i - 1] * 26
2:前i个长度只包含了u,没有us。那么加入一个s。
这里要用到容斥思想来求方案数了。首先i个组成的串的所有方案数为26^i。
组成的没有u的为25^i。那么包含u的就是26^i - 25^i,然后不包含us,即-dp[i - 1].
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e6 + 5; const int M = 3e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; LL dp[N]; LL quick_mi(LL a,LL b){ LL re = 1; while(b){ if(b & 1) re = re * a % Mod; a = a * a % Mod; b >>= 1; } return re; } int main() { int n;n = read(); dp[2] = 1; for(int i = 3;i <= n;++i){ dp[i] = (dp[i - 1] * 25 % Mod + (quick_mi(26,i - 1) - quick_mi(25,i - 1) + Mod) % Mod) % Mod; } LL ans = 0; for(int i = 1;i <= n;++i) ans = (ans + dp[i]) % Mod; printf("%lld\n",ans); system("pause"); return 0; }
J:首先剩下的数最少由两个素因子的k次构成。
对于两个数A = p1^k1 * p2^k2 * p3^k3.B = p1 ^ m1 * p2 ^ m2 * p3 *m3.
他们的LCM = p1 ^ max(k1,m1) * p2 ^ max(k2,m2) * p3 ^ max(k3,m3)。
所以我们只需要去维护素因子的最高次即可。
那么显然不是2的乘上一个2然后去增长次数的最高次为最大。
是2就乘3.
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 8e7 + 5; const int M = 5e6 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; bool vis[N]; int prime[M],tot = 0; void init(){ for(int i = 2;i < N;++i){ if(!vis[i]){ prime[++tot] = i; } for(int j = 1;j <= tot && prime[j] * i < N;++j){ vis[prime[j] * i] = 1; if(i % prime[j] == 0) break; } } } LL quick_mi(LL a,LL b){ LL re = 1; while(b){ if(b & 1) re = re * a % Mod; a = a * a % Mod; b >>= 1; } return re; } int main() { init(); int n;n = read(); if(n <= 5) printf("empty\n"); else{ LL ans = 1,ma = 3,cnt = 0; while(1){ ma *= 2; if(ma > n) break; cnt++; } ans = ans * quick_mi(2,cnt) % Mod; for(int i = 2;i <= tot && prime[i] <= n;++i){ cnt = 0; ma = 2; while(1){ ma *= prime[i]; if(ma > n) break; cnt++; } if(cnt == 0) continue; ans = ans * quick_mi(prime[i],cnt) % Mod; } printf("%lld\n",ans); } system("pause"); return 0; }