A玉桑的环星球
这题不难发现最终走的步数一定是所有数的最小公倍数,由于第i天会走i的平方布,所以最终的数应该是所有数的最小公倍数的倍数,那么根据根据平方和公式求出t天走了(t * (t + 1) * (2 * t + 1)) / 6步,也就是说我们需要求出那个最小的天数t使得这个式子取模所有数的最小公倍数为0即此时的天数t为最小的答案,而三个乘法的式子中,三个数是互质的,所以就需要去三个循环遍历三个式子的值,取公共最小t满足这个式子取模所有数的最小公倍数为0
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128
#define fi first
#define se second
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
signed main() {
int n;
cin >> n;
map<int, int> mp;
int p = 1;
for(int i = 1; i <= n; i++) {
int x;
cin >> x;
p = x / gcd(x, p) * p;
}
int pp = p;
for(int i = 2; i <= p / i; i++) {
if(p % i == 0) {
while(p % i == 0) {
p /= i;
mp[i]++;
}
}
}
if(p > 1) {
mp[1]++;
mp[2]++;
mp[p]++;
}
int cnt = (*mp.rbegin()).fi, mi = 1e18;
for(int i = 1; i <= 1e6; i++) {
ll t = i * cnt;
if(t * (t + 1) * (2 * t + 1) / 6 % pp == 0) {
mi = min(mi, (long long)t);
break;
}
}
for(int i = 1; i <= 1e6; i++) {
ll t = i * cnt - 1;
if(t * (t + 1) * (2 * t + 1) / 6 % pp == 0) {
mi = min(mi, (long long)t);
break;
}
}
for(int i = 1; i <= 1e6; i++) {
ll t = (i * cnt - 1) / 2;
if(t * (t + 1) * (2 * t + 1) / 6 % pp == 0) {
mi = min(mi, (long long)t);
break;
}
}
cout << mi;
return 0;
}
B前进者
C传递者
不要被数据误解了,画个图就出了hhh
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
if(n <= 2) {
cout << 0;
} else {
cout << 2;
}
return 0;
}
D求生者
E干饭豪的不定方程
暴力枚举a的t次方,求有多少b的k次方与其对应
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
void solve() {
int n;
cin >> n;
map<ll, ll> mp;
for(ll a = 2; ; a++) {
ll c = a * a;
if(c >= n) break;
for(; c < n; c *= a) {
mp[c]++;
}
}
ll ans = 0;
for(ll a = 2; ; a++) {
ll c = a * a;
if(c >= n) break;
for(; c < n; c *= a) {
if(mp.count(n - c)) {
ans += mp[n - c];
}
}
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
F狗头豪的数列求和
G草莓豪的斐波那契
把将小于1e18的斐波那契预处理出来,然后开始求和,如果和大于输入的n,输出此刻位置停止循环即可
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6 + 5;
ll f[N];
int main() {
ll n;
cin >> n;
f[1] = 1;
f[2] = 2;
f[3] = 3;
f[4] = 5;
ll m = 0;
for(int i = 4; f[i - 1] <= 1e18; i++) {
f[i] = f[i - 1] + f[i - 2];
m = i;
}
ll sum = 0;
for(int i = 1; i <= m; i++) {
sum += f[i];
if(sum >= n) {
cout << i;
break;
}
}
return 0;
}
H小刻觉得应该来个平衡树
这题本意是平衡树,也是个平衡树原题,但本人蒟蒻不会平衡树555,所以这题vector的insert卡过的(出题人没想到insert这么快没有造数据试,输入用cin会超时)
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
int main() {
int n;
scanf("%d", &n);
vector<int> a;
while(n--) {
int x;
scanf("%d", &x);
a.insert(lower_bound(a.begin(), a.end(), x), x);
int i = ceil((double)a.size() / 3), j = ceil((double)a.size() * 2 / 3);
cout << a[i - 1] << ' ' << a[j - 1] << endl;
}
return 0;
}
I小刻的DP题
J小刻的画图写话
说简单了就是左上角和右下角组成相同,左下角和右上角组成相同并且是前面的每个位置取反,我的做法是直接循环让左上角和右下角赋值相同,左下角和右上角赋值和前者取反,码量比较多,也可以dfs递归(码量小)
#include<bits/stdc++.h>
using namespace std;
int a[1050][1050][15];
void solve() {
int n;
cin >> n;
if(n == 0) {
cout << 1 << endl;
return;
}
a[1][1][1] = 1;
a[1][2][1] = 0;
a[2][1][1] = 0;
a[2][2][1] = 1;
if(n == 1) {
for(int i = 1; i <= 1 << n; i++) {
for(int j = 1; j <= 1 << n; j++) {
cout << a[i][j][1];
}
cout << endl;
}
return;
}
for(int k = 2; k <= 10; k++) {
int m = 1 << k - 1;
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= m; j++) {
a[i][j][k] = a[i][j][k - 1];
a[i + m][j + m][k] = a[i][j][k - 1];
}
}
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= m; j++) {
if(a[i][j][k - 1]) {
a[i + m][j][k] = 0;
a[i][j + m][k] = 0;
} else {
a[i + m][j][k] = 1;
a[i][j + m][k] = 1;
}
}
}
}
for(int i = 1; i <= 1 << n; i++) {
for(int j = 1; j <= 1 << n; j++) {
cout << a[i][j][n];
}
cout << endl;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}