写一下下午校赛的部分题目
文章目录
- ATC ABC150D Semi Common Multiple
- ATC ABC144E Gluttony
- ATC dp题单Q Flowers
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 longsigned 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 longconst int N = 2e5 + 10;int h[N], a[N];
int dp[N]; // dp[i] gaodu i jiewei de ansstruct 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';
}