QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#72952 | #4583. Concerto de Pandemic | pauloamed | TL | 1040ms | 27136kb | C++17 | 5.0kb | 2023-01-21 03:08:06 | 2023-01-21 03:08:10 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 200010;
vector<int> fans;
vector<pair<int,int>> v[MAXN];
vector<int> pos;
namespace cactus{
vector<vector<int>> get_cycles(int* to, int n){
queue<int> q;
vector<int> indeg(n, 0);
for(int i = 0; i < n; ++i) indeg[to[i]]++;
for(int i = 0; i < n; ++i) if(indeg[i] == 0)
q.push(i);
while(q.size()){
int x = q.front(); q.pop();
if(--indeg[to[x]] == 0)
q.push(to[x]);
}
vector<vector<int>> cycles;
for(int i = 0; i < n; ++i) if(indeg[i] == 1){
vector<int> cycle;
int x = to[i];
while(true){
cycle.push_back(x);
indeg[x] = 0;
if(x == i) break;
x = to[x];
}
cycles.push_back(cycle);
}
return cycles;
}
}
namespace circular_arc{
bool between(int l, int r, int x){
if(l > r) return (x >= l || x <= r);
else return (x >= l && x <= r);
}
bool intersect(pair<int,int> a, pair<int,int> b){
return (between(a.first, a.second, b.first) || between(a.first, a.second, b.second) ||
between(b.first, b.second, a.first) || between(b.first, b.second, a.second));
}
struct Point{
int x, arc_id;
bool is_l;
};
vector<pair<int,int>> v;
vector<int> gd; // last one is not in GD
Point pts[2 * MAXN];
int next[MAXN];
bool is_open[MAXN];
int n;
int time_vis[MAXN][2];
void compute_next(){
for(int i = 0; i < n; ++i){
time_vis[i][0] = time_vis[i][1] = next[i] = -1;
is_open[i] = 0;
}
queue<int> closed;
for(int i = 0; i < 6 * n; ++i){
int j = i % (2 * n);
auto [p, arc_id, is_l] = pts[j];
if(is_l){ // is L
time_vis[arc_id][0] = i;
is_open[arc_id] = 1;
}else if(is_open[arc_id]){ // is R and already openned
time_vis[arc_id][1] = i;
is_open[arc_id] = 0;
while(closed.size()){
if(closed.front() != arc_id){
if(time_vis[arc_id][0] < time_vis[closed.front()][1])
break;
}
next[closed.front()] = arc_id;
closed.pop();
}
if(next[arc_id] == -1)
closed.push(arc_id);
}
}
}
void compute_gd(const vector<int> &cycle){
gd.clear();
int i = cycle[0];
gd.push_back(i);
for(int j = 1; j < cycle.size(); ++j){
gd.push_back(cycle[j]);
if(intersect(v[i], v[cycle[j]])) break;
}
}
int get_min_clique(const vector<pair<int,int>> &_v){
v = _v;
n = v.size();
if(n == 0) return 0;
for(int i = 0; i < n; ++i){
pts[2 * i] = {v[i].first, i, 1};
pts[2 * i + 1] = {v[i].second, i, 0};
}
sort(pts, pts + 2 * n, [](Point &a, Point &b){
if(a.x == b.x) return a.is_l > b.is_l;
else return a.x < b.x;
});
compute_next();
auto cycles = cactus::get_cycles(next, n);
compute_gd(cycles[0]);
if(gd.size() == 1) return 1;
if(gd.front() == gd.back()) return gd.size() - 1;
else return gd.size();
}
}
vector<int> fanid;
bool solve(int will_walk, int p){
// cout << "------------\n";
// cout << will_walk << "\n";
int n = pos.size() / 2;
vector<pair<int,int>> intervs;
for(auto i : fanid){
int dist = 0;
int r;
{ // r
int nxt_pos = pos[i] + will_walk;
r = upper_bound(pos.begin(), pos.end(), nxt_pos) - pos.begin();
r--;
dist += r - i;
r %= n;
}
int l;
{
int nxt_pos = pos[i + n] - will_walk;
l = lower_bound(pos.begin(), pos.end(), nxt_pos) - pos.begin();
dist += i + n - l;
l %= n;
}
if(dist >= n) continue;
intervs.push_back({l, r});
}
int needed = circular_arc::get_min_clique(intervs);
return needed <= p;
}
int32_t main(){
cin.tie(NULL)->sync_with_stdio(false);
int n, m, k, p; cin >> n >> m >> k >> p;
vector<int> c(n, 0);
for(int i = 0; i < m; ++i){
int j, t; cin >> j >> t; j--;
c[j] = t;
}
for(int i = 0; i < k; ++i){
int x; cin >> x; x--;
fans.push_back(x);
}
vector<int> good;
for(int i = 0; i < n; ++i) if(c[i] == 0){
good.push_back(i);
}
if(good.size() == 1){
cout << 0 << "\n";
return 0;
}
auto id = [&](int x){
return (int) (lower_bound(good.begin(), good.end(), x) - good.begin());
};
for(auto x : fans) fanid.push_back(id(x));
for(int i = 0; i < n; ++i) if(c[i] == 0){
// i nao tem quarentena
int l = (i - 1 + n) % n;
int r = (i + 1) % n;
int cost_l = 1, cost_r = 1;
while(c[l] != 0){
cost_l += c[l] + 1;
l = (l - 1 + n) % n;
}
while(c[r] != 0){
cost_r += c[r] + 1;
r = (r + 1) % n;
}
v[id(i)].push_back({id(l), cost_l});
v[id(i)].push_back({id(r), cost_r});
}
int curr_pos = 0;
for(int i = 0; i < 2 * good.size(); ++i){
pos.push_back(curr_pos);
curr_pos += v[i % good.size()][1].second;
}
int tot = pos[good.size()];
if(solve(0, p)){
cout << 0 << "\n";
}else{
int ans = 0;
int pot = (1LL << 36);
while(pot){
int mans = ans + pot;
if(mans < tot && !solve(mans, p)){
ans = mans;
}
pot /= 2;
}
cout << ans + 1 << "\n";
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 14244kb
input:
10 4 3 2 1 2 4 4 6 2 7 5 2 5 8
output:
4
result:
ok single line: '4'
Test #2:
score: 0
Accepted
time: 1ms
memory: 13948kb
input:
8 1 3 5 1 5 4 2 7
output:
0
result:
ok single line: '0'
Test #3:
score: 0
Accepted
time: 2ms
memory: 13092kb
input:
5 2 2 1 1 14 2 14 3 5
output:
1
result:
ok single line: '1'
Test #4:
score: 0
Accepted
time: 1ms
memory: 10092kb
input:
2 1 1 1 1 200000 2
output:
0
result:
ok single line: '0'
Test #5:
score: 0
Accepted
time: 1040ms
memory: 27136kb
input:
190976 113222 55610 23475 51263 120558 10007 171596 46671 108981 117183 169457 18187 84735 149298 124718 79376 129184 28117 76880 109791 87521 114840 59510 38014 178362 41701 11344 27561 192741 173835 54534 71368 76692 122745 95537 152595 158352 43901 162441 98927 105784 22484 96000 19443 113614 370...
output:
170531
result:
ok single line: '170531'
Test #6:
score: -100
Time Limit Exceeded
input:
198722 26425 169256 110599 33948 74442 51729 66300 40369 173859 42274 73043 117803 108716 149794 151005 147161 2675 148063 166634 132585 51612 141999 182365 32951 159790 120932 290 82655 150138 49337 10396 171146 129572 33311 193079 195115 171691 180568 77905 65397 110312 156436 149966 9377 55490 12...