251120noip模拟赛总结
100 + 100 + 42 + 0 = 242
T3炸了
A - print
绿题写了
一开始读错题了,花cutezrr的cutezrr,就把代码删了
继续烧烤正解
感觉是直接模拟每一个任务给哪个打印机
注意到,我们可以把打印机分成两类:1.等待时间为
首先肯定优先用第一类的
第2类就用
每次接到一个新任务的时候,先把第二类里面能变成第一类的扔进第一类里面
第一类也是
(讲的顺序有些抽象,但考场上就是先想到第二类再想到第一类的(没错第二类就是一开始cutezrr的假做法))
然后就可以做叻:)
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 2e5 + 5;
LL n, m;
vector <int> ans[N];
set <pair <LL, int>> s1;
set <int> s0;
struct aa {
LL s, t, i;
} a[N];
bool cmp (aa x, aa y) {
return x.t < y.t;
}
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i].s >> a[i].t;
a[i].i = i;
}
for (int i = 1; i <= m; i++) {
s0.insert(i);
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++) {
for (; s1.size() && (*s1.begin()).first <= a[i].t; s0.insert((*s1.begin()).second), s1.erase(*s1.begin()));
if (s0.size()) {
int j = *s0.begin();
s0.erase(j);
ans[j].emplace_back(a[i].i);
s1.insert({a[i].t + a[i].s, j});
} else {
pair <LL, int> p = *s1.begin();
s1.erase(p);
ans[p.second].emplace_back(a[i].i);
s1.insert({p.first + a[i].s, p.second});
}
}
for (int i = 1; i <= m; i++) {
cout << ans[i].size() << ' ';
sort(ans[i].begin(), ans[i].end());
for (int j : ans[i]) {
cout << j << ' ';
}
cout << '\n';
}
return 0;
}
T2 - ship
这场T2比之前都简单:)
一眼
但是还要枚举区间,这样总共就是
于是先枚举区间右端点,然后倒过来枚举左端点,顺便把
考虑到只有
去T4烧烤了一会,决定回来把线段树打了,没想到
#include <bits/stdc++.h>
#define LL long long
#define ls k << 1
#define rs k << 1 | 1
using namespace std;
const int N = 5e3 + 5, inf = 1e9;
int id, nn, a[N], k, f[N][N], ans, n, ans1[N], tree[N];
string s[15], t;
void push_up (int k) {
tree[k] = min(tree[ls], tree[rs]);
}
void build (int k, int l, int r) {
tree[k] = inf;
if (l == r) return;
int mid = l + r >> 1;
build(ls, l, mid); build(rs, mid + 1, r);
push_up(k);
}
int query (int k, int l, int r, int l1, int r1) {
if (l >= l1 && r <= r1) return tree[k];
int mid = l + r >> 1, ret = inf;
if (mid >= l1) {
ret = query(ls, l, mid, l1, r1);
}
if (mid < r1) {
ret = min(ret, query(rs, mid + 1, r, l1, r1));
}
return ret;
}
void update (int k, int l, int r, int k1, int x) {
if (l == r) {
tree[k] = x;
return;
}
int mid = l + r >> 1;
if (mid >= k1) {
update(ls, l, mid, k1, x);
} else {
update(rs, mid + 1, r, k1, x);
}
push_up(k);
}
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> id >> nn >> k;
for (int i = 1; i <= nn; i++) {
cin >> s[i];
s[i] = ' ' + s[i];
}
cin >> t;
n = t.size();
t = ' ' + t;
for (int i = 1; i <= n; i++) {
for (int l = 1; l <= nn; l++) {
for (int j = i; j <= min(n, (int)(i + s[l].size() - 2)); j++) {
if (s[l][j - i + 1] != t[j]) break;
a[i] = max(a[i], j - i + 1);
// cout << i << ' ' << l << ' ' << j << '\n';
}
}
// cout << a[i] << ' ';
}
// cout << '\n';
for (int r = n; r >= 1; r--) {
build(1, 1, n + 1);
update(1, 1, n + 1, r + 1, 0);
for (int l = r; l >= 1; l--) {
f[l][r] = inf;
if (a[l]) {
f[l][r] = query(1, 1, n + 1, l + 1, min(r + 1, l + a[l])) + 1;
}
// cout << l << ' ' << r << ' ' << f[l][r] << '\n';
update(1, 1, n + 1, l, f[l][r]);
ans += max(0, k - f[l][r] + 1);
if (k - f[l][r] + 1 > 0) {
for (int i = l; i <= r; i++) {
ans1[i] += k - f[l][r] + 1;
}
}
}
}
cout << ans << '\n';
for (int i = 1; i <= n; i++) {
cout << ans1[i] << ' ';
}
return 0;
}
//bu yao zha qwq bu yao zha qwq bu yao zha qwq bu yao zha qwq bu yao zha qwq bu yao zha qwq bu yao zha qwq bu yao zha qwq bu yao zha qwq
但是炸了
下午上whk的时候突然想起,改到线段树之后没有按新的部分分的需求开long long!!
我居然没有开long long!!!都怪zrr!!
T4 - party
太恶心了,烧烤了一下纯暴力,发现比线段树还难打,于是跑回T3打线段树,这个题没创建文件:)
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!
long long!!