CF1765L Project Manager
设
考虑到每个没有节假日的周必然存在至少一个项目被完成,所以答案不超过
因为一个人会选择编号较小的项目推进,所以按编号从小到大依次模拟每个项目的进度。设当前处理到项目的第
星期一到星期日相互独立,因此考虑对一星期的七天,如果 map 维护并查集即可。注意这里并查集是一条链,所以执行 find 的总次数为总点数的线性,而每新增一个点,都意味着找到一个工作且未被占用的后继,所以总点数为
时间复杂度 ios::sync_with_stdio(0)。
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 2e5 + 5;
constexpr int M = 3e6 + 5;
const string week[8] = {
"",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
int n, m, k, w[N][8], suc[M];
map<int, int> mp[N];
int f(int id, int z) {
z = suc[z];
auto it = mp[id].find(z);
if(it == mp[id].end() || it->second == z) return z;
return it->second = f(id, it->second);
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#ifdef ALEX_WEI
FILE* IN = freopen("1.in", "r", stdin);
FILE* OUT = freopen("1.out", "w", stdout);
#endif
cin >> n >> m >> k;
for(int i = 1; i < M; i++) suc[i] = i;
for(int i = 1; i <= n; i++) {
int cnt;
cin >> cnt;
string day;
while(cnt--) {
cin >> day;
for(int j = 1; j <= 7; j++) {
if(day == week[j]) w[i][j] = 1;
}
}
}
for(int i = 1; i <= m; i++) {
int h;
cin >> h;
if(h < M) suc[h] = h + 7;
}
for(int i = M - 8; i; i--) suc[i] = suc[suc[i]];
for(int _ = 1; _ <= k; _++) {
int p, a, cur = 0;
cin >> p;
while(p--) {
cin >> a;
int nxt = M;
for(int i = 1; i <= 7; i++) {
if(w[a][(cur + i - 1) % 7 + 1]) nxt = min(nxt, f(a, cur + i));
if(nxt == cur + i) break;
}
mp[a][nxt] = nxt + 7, cur = nxt;
}
cout << cur << " ";
}
cout << "\n";
return 0;
}
/*
g++ L.cpp -o L -std=c++14 -O2 -DALEX_WEI
*/