2024.11.26 周二日常
1.2025.2.19——15002.11.23 周六3.11.24 周日4.11.25 周一日常
5.2024.11.26 周二日常
6.2024.11.27 周三7.2024.11.28周四8.2024.11.29 周五9.2024.11.30 周六10.2024.12.1 周日11.2024.12.2 周一12.2024.12.3 周二13.2024.12.4 周三14.2024.12.5 周四15.2024.12.7 周六16.2024.12.8 周日17.2024.12.9 周一18.2024.12.10 周二19.2024.12.11 周三20.2024.12.12 周四21.2024.12.13 周五22.2024.12.14 周六23.2024.12.16 周一24.2024.12.17 周二25.2024.12.18 周三26.2024.12.19 周四27.2024.12.20 周五28.2024.12.21 周六29.2024.12.22 周日30.2024.12.23 周一31.2024.12.24 周四32.2024.12.25 周三33.2024.12.26 周四34.2024.12.27 周五35.2024.12.28 周六36.2024.12.29 周日37.2024.12.30 周一38.2025.1.5——120039.2025.1.12——120040.2025.1.14——120041.2025.1.15——120042.2025.1.16——120043.2025.1.17——120044.2025.1.18——130045.2025.1.19——130046.2025.1.20——130047.2025.1.21——130048.2025.1.22——130049.2025.1.24——140050.2025.1.26——140051.2025.2.8——140052.2025.2.9——140053.2025.2.10——140054.2025.2.14——140055.2025.2.15——140056.2025.2.17——14002024.11.26 周二日常
-
Q1. 1200
给定一数组k(代表n个人的倍率),设在每个人上投资为xi,若其胜利则获k*xi,最终一人胜利。问是否可以保证无论谁胜利,收益大于总投资的方案。(n<=20,k<=50) -
Q2. 1300
给定一数组,问最小的k使所有长度为k的区间按位或相等。 -
Q3. 1500
给定一数组,定义MAD:数组中出现大于一次且最大的数。操作直到数组全为0:每次操作i:1->n a[i]=MAD{a[i]的前缀数组}。问所有操作前数组和的总和。 -
A1. 补
解法1. 二分总投资s,若总投资为x,则x+1也可满足,呈单调性。检查:给每人合法的最小投资判断总投资sum<=x。找到最小合法s,进行分配。
解法2. 投入1/ki可获1,需满足:求和1/ki<1 两边乘lcm。判断每人投资lcm/k[i]是否合法。 -
A2. 48mins 读错题硬控20min,st板子不完善
二分加ST表:若x合法,则x+1一定合法,k属于[x,n]。每次检查使用ST表查询区间按位或依次判断。 -
A3. 补 抽象问题造样例引导思考 样例不全面导致思考不全面
观察发现题吧?造一个好数据,模拟发现关键点:1.操作后数组单调不降 2.操作1次可能有单个元素段,操作2次即为多个连续相同元素子数组。3.然后每次操作就是向右平移,找一个好的计算方法也很重要:根据到n+1位置的距离计算每个元素出现的次数。
A1.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' //
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
_();
return 0;
}
// 给定一数组k(代表n个人的倍率),设在每个人上投资为xi,若其胜利则获k*xi,最终一人胜利。问是否可以保证无论谁胜利,收益大于总投资的方案。(n<=20,k<=50)
// 1. 二分总投资s,若总投资为x,则x+1也可满足,呈单调性。检查:给每人合法的最小投资判断总投资sum<=x。找到最小合法s,进行分配。
// 2. 投入1/ki可获1,需满足:求和1/ki<1 两边乘lcm。判断每人投资lcm/k[i]是否合法。
// 2.数学
void _()
{
int n;
cin >> n;
vector<int> k(n);
for (int &_k : k)
cin >> _k;
auto lcm = [](int a, int b)
{
return a / __gcd(a, b) * b;
};
int L = k.front();
for (int i = 1; i < n; i++)
L = lcm(L, k[i]);
int s = 0;
for (auto k : k)
s += L / k;
if (s >= L)
{
cout << -1 << endl;
return;
}
for (auto k : k)
cout << L / k << ' ';
cout << endl;
}
// 1.二分
// void _()
// {
// int n;
// cin >> n;
// vector<int> k(n);
// for (int &_k : k)
// cin >> _k;
// int l = 0, r = 1e9 * n + 1;
// auto ok = [&](int x)
// {
// int sum = 0;
// for (int i = 0; i < n; i++)
// sum += x / k[i] + 1;
// return sum <= x;
// };
// while (r - l - 1)
// {
// int mid = l + r >> 1;
// if (ok(mid))
// r = mid;
// else
// l = mid;
// }
// if (ok(r))
// {
// for (int i = 0; i < n; i++)
// cout << r / k[i] + 1 << ' ';
// cout << endl;
// }
// else
// cout << -1 << endl;
// }
A2.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' // 交互/调试 关
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
void _();
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while (T--)
_();
return 0;
}
// 给定一数组,问最小的k使所有长度为k的区间按位或相等。
// 二分加ST表:若x合法,则x+1一定合法,k属于[x,n]。每次检查使用ST表查询区间按位或依次判断。
// 48min
void _()
{
int n;
cin >> n;
vector<int> a(n + 1);
vector<vector<int>> dp(n + 1, vector<int>(32)); // 内存超限 必要时关long long
for (int i = 1; i <= n; i++)
cin >> a[i];
// init
for (int j = 0; j < 30; j++) // j 是每一层状态
for (int i = 1; i <= n; i++)
{
if (i + (1 << j) - 1 > n)
continue;
if (!j)
dp[i][j] = a[i];
else
dp[i][j] = dp[i][j - 1] | dp[i + (1 << j - 1)][j - 1];
}
// query
auto ask = [&](int l, int r)
{
int k = log(r - l + 1) / log(2);
return dp[l][k] | dp[r + 1 - (1 << k)][k];
};
auto ok = [&](int x)
{
int ans = 0;
for (int i = 1; i + x - 1 <= n; i++)
{
auto re = ask(i, i + x - 1);
if (i == 1)
ans = re;
else
{
if (re - ans)
return 0;
}
}
return 1;
};
// bug(111);
int l = 0, r = n;
while (r - l - 1)
{
int mid = l + r >> 1;
if (ok(mid))
r = mid;
else
l = mid;
}
cout << r << endl;
}
A3.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' // 交互/调试 关
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
void _();
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while (T--)
_();
return 0;
}
// 抽象问题造样例引导思考 样例不全面导致思考不全面
// 给定一数组,定义MAD:数组中出现大于一次且最大的数。操作直到数组全为0:每次操作i:1->n a[i]=MAD{a[i]的前缀数组}。问所有操作前数组和的总和。
// 观察发现题吧?造一个好数据,模拟发现关键点:1.操作后数组单调不降 2.操作1次可能有单个元素段,操作2次即为多个连续相同元素子数组。
// 3.然后每次操作就是向右平移,找一个好的计算方法也很重要:根据到n+1位置的距离计算每个元素出现的次数。
void _()
{
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
auto f = [&]()
{
int sum = 0, tmax = 0;
map<int, int> cnt;
for (int i = 1; i <= n; i++)
{
sum += a[i];
cnt[a[i]]++;
if (cnt[a[i]] > 1)
tmax = max(tmax, a[i]);
a[i] = tmax;
}
return sum;
};
int res = f() + f();
for (int i = n; i; i--)
res += a[i] * (n - i + 1);
cout << res << endl;
}
// // 34mins-36mins-55mins-补
// void _()
// {
// int n;
// cin >> n;
// int sum = 0;
// vector<int> a(n + 1);
// for (int i = 1; i <= n; i++)
// cin >> a[i], sum += a[i];
// int tmax = 0;
// map<int, int> cnt;
// map<int, int> ans_cnt;
// for (int i = 1; i <= n; i++)
// {
// cnt[a[i]]++;
// if (cnt[a[i]] > 1)
// tmax = max(tmax, a[i]);
// if (tmax)
// ans_cnt[tmax]++;
// }
// vector<pair<int, int>> ans;
// for (auto [x, ct] : ans_cnt)
// ans.push_back({x, ct});
// sort(ans.rbegin(), ans.rend());
// int pre = 0, res = sum;
// for (int i = 0; i < ans.size(); i++)
// {
// auto [x, k] = ans[i];
// // bug2(x, k);
// res += pre * x * k;
// if (k - 1)
// pre += k;
// if (k == 1 && pre && i) // 坑点
// continue;
// res += x * k * (k + 1) >> 1;
// }
// // bug(tmax);
// cout << res << endl;
// }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!