#pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include using namespace std; using pii=pair; using tii=tuple; using qii=tuple; using ll=long long; using ull=unsigned long long; using ld=long double; constexpr int INF=1e9; constexpr ll INF_ll=1e18; #define rep(i,n) for (int i=0;i<(int)(n);i++) #define replr(i,l,r) for (int i=(int)(l);i<(int)(r);i++) #define all(v) v.begin(),v.end() #define len(v) ((int)v.size()) template inline bool chmin(T &a,const T &b){ if(a>b){ a=b; return true; } return false; } template inline bool chmax(T &a,const T &b){ if(a(now-start).count(); return ms; } int get_ms_all_program(){ auto now=chrono::steady_clock::now(); int ms=chrono::duration_cast(now-program_start).count(); return ms; } } mt19937 mt; uint32_t rand_int(uint32_t r){ //[0,r) assert(r!=0); return ((uint64_t)mt()*r)>>32; } int rand_int(int l,int r){ //[l,r) assert(l T get_random_element(const vector &v){ assert(!v.empty()); return v[rand_int(len(v))]; } template void add(vector &a,vector b){ for(auto i:b) a.push_back(i); } template SA_State SA(const SA_State &first_state){ SA_State state=first_state,best_state=state; int loop_cnt=0,accept_cnt=0,update_cnt=0; int ms=0; double temp=start_temp; Timer::snap(); while(true){ if(true){ ms=Timer::get_ms(); if(limit_ms<=ms) break; //double t=(double)ms/limit_ms; temp=start_temp-(start_temp-end_temp)/limit_ms*ms; //temp=pow(start_temp,1-t)*pow(end_temp,t); } loop_cnt++; double accept_diff=log(rand_double())*temp; bool accepted=state.modify(accept_diff); if(accepted){ accept_cnt++; if(best_state.score X,Y,W; array,N> W_score; ll W_score_sum=0; struct Plan{ int a,b; int s,t; auto operator<=>(const Plan &other) const{ return this->t<=>other.t; } }; array P; array,N> D; array,N> Is_target; array Time_string; array Target_times; namespace Solver{ void calc_times(int j,int t,const vector &sorted_plans,array &s){ s.fill(-INF); s[j]=t; for(const auto &plan:sorted_plans){ if(plan.t<=s[plan.b]&&s[plan.a],Target_size*N> memo_s_sq; array,N> square_t_plans; array,N> square_next_update; struct Candidate{ ll score=0; int parent=-1; vector plans; auto operator<=>(const Candidate &other) const{ return this->score<=>other.score; } }; struct State{ array,K> ans; vector all_plans; ll calc_now_ci(int j,const auto &s_sq,const auto &s_ci){ int sum=0; rep(i,N){ sum+=Is_target[j][i]*W[i]*(s_sq[i],N> circle_t_plans; for(auto plan:all_plans){ circle_t_plans[plan.b].push_back(plan.t); } rep(i,N) sort(all(circle_t_plans[i])); array,N> circle_next_update; rep(j,N){ circle_next_update[j].fill(false); rep(t_idx,Target_size-1){ auto itr_circle=upper_bound(all(circle_t_plans[j]),Target_times[t_idx]); if(itr_circle!=circle_t_plans[j].end()&&*itr_circle<=Target_times[t_idx+1]){ circle_next_update[j][t_idx]=true; } } } ll ci=0; for(int j=0;j s_ci; calc_times(j,Target_times.front(),all_plans,s_ci); auto s_sq=memo_s_sq[j*Target_size]; ll now_ci=calc_now_ci(j,s_sq,s_ci); rep(t_idx,Target_size){ ci+=now_ci; if(t_idx+1(const State &other) const{ return this->score<=>other.score; } vector get_candidates(int parent){ sort(all(all_plans)); reverse(all(all_plans)); array,N> circle_t_plans; for(auto plan:all_plans){ circle_t_plans[plan.b].push_back(plan.t); } rep(i,N) sort(all(circle_t_plans[i])); array,N> circle_next_update; rep(j,N){ circle_next_update[j].fill(false); rep(t_idx,Target_size){ auto itr_circle=upper_bound(all(circle_t_plans[j]),Target_times[t_idx]); if(itr_circle!=circle_t_plans[j].end()&&*itr_circle<=Target_times[t_idx+1]){ circle_next_update[j][t_idx]=true; } } } array,N>,N> point; rep(j,N){ rep(i,N){ point[j][i].fill(0); } } for(int j=0;j s_ci; calc_times(j,Target_times.front(),all_plans,s_ci); auto s_sq=memo_s_sq[j*Target_size]; int cnt=0; rep(t_idx,Target_size){ int t=Target_times[t_idx]; rep(i,N){ if(s_sq[i],T> dp; array,T> pre; rep(t,T){ dp[t].fill(0); pre[t].fill({-1,-1}); } for(int t=T-1;0<=t;t--){ rep(j,N){ if(dp[t][j]<0) continue; if(0<=t-1){ if(chmax(dp[t-1][j],dp[t][j])) pre[t-1][j]={t,j}; } rep(i,N){ if(i==j) continue; int s=t-D[j][i]; if(0<=s){ if(chmax(dp[s][i],dp[t][j]+point[j][i][t])) pre[s][i]={t,j}; } } } } vector ret; rep(n,N){ ll now=0; int nt=-1,ni=n; for(int t=T-1;0<=t;t--){ if(chmax(now,dp[t][n])) nt=t; } vector plans; while(true){ auto [pt,pi]=pre[nt][ni]; if(pt==-1) break; if(ni!=pi){ plans.emplace_back(ni,pi,nt,pt); } nt=pt; ni=pi; } ret.emplace_back(score+now,parent,plans); } sort(all(ret)); reverse(all(ret)); ret.resize(11); return ret; } void advance(Candidate candidate){ ans[k]=candidate.plans; add(all_plans,candidate.plans); score=calc_true_score(); k++; } }; auto beam_search(){ constexpr int W=8; vector dp; dp.push_back(State()); rep(k,K){ cerr << k << " " << dp[0].score << " " << len(dp) << endl; priority_queue,greater> pq; rep(w,W){ if(len(dp)<=w) break; vector candidates=dp[w].get_candidates(w); for(auto candidate:candidates){ State state=dp[w]; state.advance(candidate); if(len(pq)==W&&state<=pq.top()) continue; pq.push(state); if(W all_plans(all(P)); sort(all(all_plans)); reverse(all(all_plans)); rep(j,N){ rep(t_idx,Target_size){ calc_times(j,Target_times[t_idx],all_plans,memo_s_sq[j*Target_size+t_idx]); } } rep(i,M){ square_t_plans[P[i].b].push_back(P[i].t); } rep(i,N) sort(all(square_t_plans[i])); rep(j,N){ square_next_update[j].fill(false); rep(t_idx,Target_size){ auto itr_square=upper_bound(all(square_t_plans[j]),Target_times[t_idx]); if(itr_square!=square_t_plans[j].end()&&*itr_square<=Target_times[t_idx+1]){ square_next_update[j][t_idx]=true; } } } array,K> ans=beam_search(); rep(k,K){ cout << len(ans[k]) << '\n'; rep(i,len(ans[k])){ if(1<=i){ assert(ans[k][i-1].b==ans[k][i].a); assert(ans[k][i-1].t<=ans[k][i].s); } assert(0<=ans[k][i].s&&ans[k][i].s> n >> r; assert(n==N); assert(r==R); rep(i,N) cin >> X[i] >> Y[i] >> W[i]; int m; cin >> m; assert(m==M); rep(i,M){ int a,b; string s,t; cin >> a >> s >> b >> t; a--; b--; P[i].a=a; P[i].b=b; int sx=stoi(s.substr(0,2)),sy=stoi(s.substr(3,2)); int tx=stoi(t.substr(0,2)),ty=stoi(t.substr(3,2)); P[i].s=(sx*60+sy-6*60)/5; P[i].t=(tx*60+ty-6*60)/5; } int k; cin >> k; assert(k==K); rep(i,N){ rep(j,N){ double d=hypot(X[i]-X[j],Y[i]-Y[j]); int t=ceil(60*d/800+40); while(t%5!=0) t++; D[i][j]=t/5; } } for(int i=6;i<=21;i++){ for(int j=0;j<60;j+=5){ string sx=to_string(i),sy=to_string(j); while(len(sx)<2) sx.insert(sx.begin(),'0'); while(len(sy)<2) sy.insert(sy.begin(),'0'); Time_string[(i*60+j-6*60)/5]=sx+":"+sy; if(i==21) break; } } int idx=0; for(int i=11;i<=21;i++){ for(int j=0;j<60;j+=30){ Target_times[idx]=(i*60+j-6*60)/5; idx++; if(i==21) break; } } rep(i,N){ rep(j,N){ ll x=((ll)(X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]))*16; if(R*R<=x){ Is_target[i][j]=true; }else{ Is_target[i][j]=false; } } } rep(i,N){ W_score[i].fill(0); rep(j,N){ if(Is_target[i][j]) W_score[i][j]=(ll)W[i]*W[j]; } } W_score_sum=0; rep(i,N){ rep(j,N){ if(!Is_target[i][j]) continue; rep(_,Target_size){ W_score_sum+=W_score[i][j]; } } } Solver::solve(); exit(0); }