应该这么想:要维护每天哪些人干哪些活,那我可以直接维护每天哪些人干了哪些项目吗,{int,vector<int>}
但题目有个条件,每个人都干优先级最高的事情,所以后面直接vector不好做,信息不能合在一起维护,所以拆开,一个维护每个人手头上(即当前)的blocking项目数
,另一个维护每个人手头上(即当前)的项目有哪些
——这样分开来维护就能实现当某个人完成一个任务的时候也能确定他完成的是哪个project了(因为后者用set维护);
注意到需要维护的主体之间的关系是:工作——人,人——时间(枚举时间)
到这里实际上主要的功能就结束了,接下来想如何维护刚才的两个东西——得有一个vector<>del
记录删了哪些project,这样好每天结束之后更新每个人的项目数和有哪些项目;得有个lst指针
记录每个project的part进行到哪了;同时因为人是受时间轴限制而工作不受限,所以直接开7个向量存每个人手头上(即当前)的blocking项目数
,维护这7天的每天;后者每个人手头上(即当前)的项目有哪些
并不需要,独立于时间轴;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+15;
const int mo = 998244353;
#define pb push_back
#define pii pair<int,int>
#define ft first
#define sd second
#define debug1(x) cerr<<"! "<<x<<endl;
#define debug2(x,y) cerr<<"# "<<x<<" "<<y<<endl;
void slv(){
int n,m,k;cin>>n>>m>>k;
map<string,int>wdy;//whichday
wdy["Monday"]=0; wdy["Tuesday"]=1; wdy["Wednesday"]=2;
wdy["Thursday"]=3; wdy["Friday"]=4; wdy["Saturday"]=5; wdy["Sunday"]=6;
vector<vector<int>>wkd(n,vector<int>(7));//is_workday?
for(int i=0;i<n;i++){
int nm;cin>>nm;
for(int j=0;j<nm;j++){
string tmp;cin>>tmp;
wkd[i][wdy[tmp]]=1;
}
}
set<int>ihy;//isholidays?
for(int i=0;i<m;i++){
int x;cin>>x;x--;ihy.insert(x);
}
vector<vector<int>>p(k);//which part?
for(int i=0;i<k;i++){
int nm;cin>>nm;
p[i].resize(nm);
for(int &k:p[i]){
cin>>k;k--;//check
}
}
//因为你并不知道这个人是第什么时候做这个项目
vector<map<int,int>>cur(7);//which day,which one,do how much things
vector<set<int>>wk(n);//worker
vector<int>lst(k),ans(k);
for(int i=0;i<k;i++)for(int j=0;j<7;j++)if(wkd[p[i][0]][j]){
cur[j][p[i][0]]++;
}
for(int i=0;i<k;i++){
wk[p[i][0]].insert(i);//这个映射关系我想了很久
}
int done=0;
for(int d=0;;d++){//for_day
if(ihy.count(d)){
continue;
}
int nd=d%7;//nowday
vector<int>nwr,del;//now_worker del_project
for(auto k:cur[nd]){
nwr.pb(k.ft);
}
for(auto x:nwr){
for(int i=0;i<7;i++){
auto it=cur[i].find(x);
if(it!=cur[i].end()){
if(it->sd==1)
cur[i].erase(it);
else
--it->sd;
}
}
int y=*wk[x].begin();
del.pb(y);
wk[x].erase(wk[x].begin());
}
int sz=nwr.size();
for(int i=0;i<sz;i++){
int y=del[i];
lst[y]++;
if(lst[y]==p[y].size()){
ans[y]=d;
++done;
continue;
}
wk[p[y][lst[y]]].insert(y);
for(int j=0;j<7;j++)if(wkd[p[y][lst[y]]][j]){
++cur[j][p[y][lst[y]]];
}
}
if(done==k) break;
}
for(int i=0;i<k;i++) cout<<ans[i]+1<<" ";
cout<<'\n';
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
slv();
}