QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#72952#4583. Concerto de PandemicpauloamedTL 1040ms27136kbC++175.0kb2023-01-21 03:08:062023-01-21 03:08:10

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-21 03:08:10]
  • 评测
  • 测评结果:TL
  • 用时:1040ms
  • 内存:27136kb
  • [2023-01-21 03:08:06]
  • 提交

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";

  }

}

詳細信息

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...

output:


result: