2019牛客暑期多校训练营(第九场)
题号 | 标题 | 已通过代码 | 题解/讨论 | 通过率 | 团队的状态 |
---|---|---|---|---|---|
A | The power of Fibonacci | 点击查看 | 进入讨论 | 34/152 | 未通过 |
B | Quadratic equation | 点击查看 | 进入讨论 | 329/741 | 通过 |
C | Inversions of all permutations | 点击查看 | 进入讨论 | 21/34 | 未通过 |
D | Knapsack Cryptosystem | 点击查看 | 进入讨论 | 533/2123 | 通过 |
E | All men are brothers | 点击查看 | 进入讨论 | 366/938 | 通过 |
F | Birthday Reminders | 点击查看 | 进入讨论 | 5/11 | 未通过 |
G | Checkers | 点击查看 | 进入讨论 | 5/8 | 未通过 |
H | Cutting Bamboos | 点击查看 | 进入讨论 | 145/628 | 已补 |
I | KM and M | 点击查看 | 进入讨论 | 15/253 | 5yisdf |
J | Symmetrical Painting | 点击查看 | 进入讨论 | 195/797 | 已补 |
B
https://www.cnblogs.com/1625--H/p/11382466.html
D
折半搜索,36/2 = 18,状压表示\(2^{18}\) 个结果,然后前一半与后一半去匹配。
#include <bits/stdc++.h>
using namespace std;
int n;
long long s;
long long a[70];
vector<long long> L, R;
vector<pair<long long, long long> > Ls, Rs;
void gao(const vector<long long>& A, vector<pair<long long, long long> >& As) {
int n = A.size();
for (int i = 0; i < 1 << n; i++) {
long long s = 0;
for (int j = 0; j < n; j++) {
if (i >> j & 1) {
s += A[j];
}
}
As.push_back(make_pair(s, i));
}
sort(As.begin(), As.end());
}
long long work() {
int i = 0, j = Rs.size() - 1;
while (i < Ls.size() && j >= 0) {
if (Ls[i].first + Rs[j].first < s) {
i++;
} else if (Ls[i].first + Rs[j].first > s) {
j--;
} else {
return Rs[j].second << L.size() | Ls[i].second;
}
}
assert(false);
}
int main() {
cin >> n >> s;
for (int i = 0; i < n; i++) {
cin >> a[i];
if (i < n / 2) {
L.push_back(a[i]);
} else {
R.push_back(a[i]);
}
}
gao(L, Ls);
gao(R, Rs);
long long ans = work();
for (int i = 0; i < n; i++) {
printf("%d", (int)(ans >> i & 1));
}
printf("\n");
return 0;
}
E
https://www.cnblogs.com/1625--H/p/11359772.html
H
队友补的
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
int n, m, cnt, len;
int a[MAXN];
int b[MAXN];
int t[MAXN];
int num[MAXN << 5];
int ls[MAXN << 5];
int rs[MAXN << 5];
double sum[MAXN << 5];
int build(int l, int r) {
int rt = ++cnt;
sum[0] = 0, num[0] = 0;
int mid = l + r >> 1;
if(l < r) {
ls[rt] = build(l, mid);
rs[rt] = build(mid + 1, r);
}
return rt;
}
int add(int o, int l, int r, int k, int v) {
int rt = ++cnt;
ls[rt] = ls[o]; rs[rt] = rs[o]; sum[rt] = sum[o] + 1.0 * v; num[rt] = num[o] + 1;
int mid = l + r >> 1;
if(l < r)
if(k <= mid) ls[rt] = add(ls[o], l, mid, k, v);
else rs[rt] = add(rs[o], mid + 1, r, k, v);
return rt;
}
double query(int ql, int qr, int l, int r, double k, int tot) {
if(l == r) return k / (1.0 * (num[qr] - num[ql] + tot));
int mid = l + r >> 1;
double lsum = sum[ls[qr]] - sum[ls[ql]];
double rsum = 1.0 * mid * (num[rs[qr]] - num[rs[ql]] + tot);
if(lsum + rsum > k) return query(ls[ql], ls[qr], l, mid, k, tot + num[rs[qr]] - num[rs[ql]]);
else return query(rs[ql], rs[qr], mid + 1, r, k - lsum, tot);
}
int main() {
cnt = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
sort(b + 1, b + 1 + n);
len = unique(b + 1, b + 1 + n) - b - 1;
t[0] = build(0, 100000);
for(int i = 1; i <= n; i++) t[i] = add(t[i - 1], 0, 100000, a[i], a[i]);
while(m--) {
int l, r, x, y;
scanf("%d%d%d%d", &l, &r, &x, &y);
double tmp = 1.0 * (sum[t[r]] - sum[t[l - 1]]) / (1.0 * y);
printf("%.8lf\n", query(t[l - 1], t[r], 0, 100000, tmp * (y - x), 0));
}
return 0;
}
ps:主席树也不是很难,得赶快学了。
J
注:转载请注明出处