写一下下午校赛的部分题目
ATC ABC150D Semi Common Multiple
下午不知道怎么糊出来的做法,可以转换成x一定要是a/2
的奇数倍,所以输入a的时候先把都除以2,然后找lcm,判断lcm是不是所有数的奇数倍,是的话答案就是m以内的所有lcm的奇数倍
#include <bits/stdc++.h>
using namespace std;
#define int long long
using i64 = long long;
typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;
int lcm(int a, int b)
{
return a * b / __gcd(a, b);
}
void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(n);
int res = 1;
for (int i = 0; i < n; i ++ )
{
cin >> a[i];
a[i] /= 2;
res = lcm(res, a[i]);
}
bool flag = false;
for (int i = 0; i < n; i ++ )
{
if ((res / a[i]) % 2 == 0) flag = true;
}
if (res > m || flag)
{
cout << 0 << '\n';
return;
}
cout << (m / res + 1) / 2 << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
}
ATC ABC144E Gluttony
二分+贪心,小的a一定配大的b
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int n, k;
cin >> n >> k;
vector<int> a(n), b(n);
for (int i = 0; i < n; i ++ ) cin >> a[i];
for (int i = 0; i < n; i ++ ) cin >> b[i];
sort(a.begin(), a.end());
sort(b.begin(), b.end(), greater<int>());
int l = 0, r = 1e15;
auto check = [&](int x)
{
int kk = k;
for (int i = 0; i < n; i ++ )
{
if (a[i] * b[i] > x)
{
int tmp = x / b[i];
kk -= a[i] - tmp;
if (kk < 0) return false;
}
}
return true;
};
while (l < r)
{
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout << r << '\n';
}
ATC dp题单Q Flowers
本来想了很久单调栈单调队列优化dp的,但是发现还是没办法处理,之后想到可以用线段树来维护区间最大值,然后就愉快ac
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int h[N], a[N];
int dp[N]; // dp[i] gaodu i jiewei de ans
struct Node
{
int l, r;
int maxx;
} tr[N * 4];
void pushup(Node& u, Node& l, Node& r)
{
u.l = l.l, u.r = r.r;
u.maxx = max(l.maxx, r.maxx);
}
void pushup(int u)
{
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r)
{
tr[u] = {l, r};
if (l == r) return;
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
}
void modify(int u, int pos, int x)
{
if (tr[u].l == pos && tr[u].r == pos)
{
tr[u].maxx = x;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if (pos <= mid) modify(u << 1, pos, x);
else modify(u << 1 | 1, pos, x);
pushup(u);
}
Node query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid) return query(u << 1, l, r);
else if (l > mid) return query(u << 1 | 1, l, r);
else
{
Node res;
auto lt = query(u << 1, l, mid);
auto rt = query(u << 1 | 1, mid + 1, r);
pushup(res, lt, rt);
return res;
}
}
signed main()
{
int n;
cin >> n;
build(1, 1, n);
for (int i = 1; i <= n; i ++ ) cin >> h[i];
for (int i = 1; i <= n; i ++ ) cin >> a[i];
for (int i = 1; i <= n; i ++ )
{
auto res = query(1, 0, h[i] - 1);
dp[h[i]] = res.maxx + a[i];
modify(1, h[i], dp[h[i]]);
}
int ans = 0;
for (int i = 1; i <= n; i ++ ) ans= max(ans, dp[i]);
cout << ans << '\n';
}