QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#138791#6520. Classic ProblemminhcoolRE 3ms15868kbC++144.9kb2023-08-12 11:19:482023-08-12 11:19:48

Judging History

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

  • [2023-08-12 11:19:48]
  • 评测
  • 测评结果:RE
  • 用时:3ms
  • 内存:15868kb
  • [2023-08-12 11:19:48]
  • 提交

answer

#define local
#ifndef local
#include ""
#endif
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define int long long
#define fi first
#define se second
#define pb push_back
//#define mp make_pair

typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef pair<ii, ii> iiii;

const int N = 3e5 + 5;

const int oo = 1e18 + 7, mod = 1e9 + 7;

mt19937 rng(1);

int rnd(int l, int r){
	int temp = rng() % (r - l + 1);
	return abs(temp) + l;
}

struct hashy{
	int operator()(const ii& a)const{
		return (a.fi * 123456789 | a.se);
	}
};
unordered_set<ii, hashy> uos;

gp_hash_table<int, int> mp;
//gp_hash_table<ii, int, hashy> mp;

int n, m;
vector<iii> edges;

int rt[N];
vector<int> nodes[N];// the nodes that are available in the component

int answer = 0;

void merge(int x, int y, int w){
	x = rt[x], y = rt[y];
	if(x == y) return;
	answer += w;
	if(nodes[x].size() < nodes[y].size()) swap(x, y);
	for(auto it : nodes[y]){
		rt[it] = x;
		nodes[x].pb(it);
	}
	nodes[y].clear();
}

int cnt;

// left-right of each node
int le[N], ri[N];

// current edge with minimum weight that connects with node u
ii mini[N];

// nodes that are not in the same component as this component
set<int> remaining;

ii find_mn(int node){// find the minimum distance from a node to another node diff component
	ii ans = mini[node];
	//cout << "CUR" << " " << node << "\n";
	//cout << "CUR " << node << " " << ans.fi << "\n";
	set<int>::iterator it = remaining.lower_bound(node), it2 = it;
	for(; it != remaining.end(); it++){
		if(uos.find({node, (*it)}) == uos.end()){
			//cout << "OK " << node << " " << (*it) << '\n';
			ans = min(ans, {le[(*it)] - ri[node], rt[(*it)]});
			break;
		}
	}
	it = it2;
	if(it == remaining.begin()) return ans;
	it--;
	for(; ; it--){
		if(uos.find({node, (*it)}) == uos.end()){
			//cout << "OK " << node << " " << (*it) << '\n';
			ans = min(ans, {le[node] - ri[(*it)], rt[(*it)]});
			break;
		}
		if(it == remaining.begin()) break;
	}
	return ans;
}

void init(){
	edges.clear();
	cnt = answer = 0;
	remaining.clear();
	uos.clear();
	mp.clear();
	//diffs.clear();
}

#ifdef local
void process(){
	cin >> n >> m;
	init();
	if(!m){
		cout << n - 1 << "\n";
		return;
	}
	vector<int> diffs;
	for(int i = 1; i <= m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		//cout << w << "\n";
		edges.pb({{x, y}, w});
		diffs.pb(x), diffs.pb(y);
	}
	// first, clear out the parts that are not part of any segments, and therefore we have O(n) nodes
	sort(diffs.begin(), diffs.end());
	diffs.resize(unique(diffs.begin(), diffs.end()) - diffs.begin());
	//cout << diffs.size() << "\n";
	//return;
	if(diffs[0] >= 2){
		cnt++;
		le[cnt] = 1;
	}
//return;
	for(int i = 0; i < diffs.size(); i++){
		cnt++;
		le[cnt] = diffs[i];
		mp[diffs[i]] = cnt;
		if((i + 1) < diffs.size() && diffs[i + 1] != (diffs[i] + 1)){
			cnt++;
			le[cnt] = diffs[i] + 1;
		}
	}
	//return;
	if(diffs.back() != n){
		cnt++;
		le[cnt] = diffs.back() + 1;
	}
	le[cnt + 1] = n + 1;
	for(int i = 1; i <= cnt; i++) nodes[i].clear();
	for(int i = 1; i <= cnt; i++){
		ri[i] = le[i + 1] - 1;
		answer += (ri[i] - le[i]);
		nodes[i].pb(i);
		rt[i] = i;
		//cout << le[i] << " " << ri[i] << "\n";
	}
	//return;
	//return;
	for(int itr = 1; itr <= 30; itr++){
		uos.clear();
		if(nodes[rt[1]].size() == cnt) break;
		set<int> roots;
		for(int i = 1; i <= cnt; i++) roots.insert(rt[i]);
		for(int i = 1; i <= cnt; i++) mini[i] = {oo, oo};
		for(auto it : edges){
			if(rt[mp[it.fi.fi]] == rt[mp[it.fi.se]]) continue;
			mini[mp[it.fi.fi]] = min(mini[mp[it.fi.fi]], {it.se, rt[mp[it.fi.se]]});
			mini[mp[it.fi.se]] = min(mini[mp[it.fi.se]], {it.se, rt[mp[it.fi.fi]]});
			//cout << mp[it.fi.fi] << " " << mp[it.fi.se] << "\n";
			uos.insert({mp[it.fi.fi], mp[it.fi.se]});
			uos.insert({mp[it.fi.se], mp[it.fi.fi]});
		}
		for(int i = 1; i <= cnt; i++) remaining.insert(i);
		vector<iii> candidates;
		//return;
		//if(itr == 2) continue;
		for(auto it : roots){
			for(auto it2 : nodes[it]) remaining.erase(it2);
			ii minimum = {oo, oo};
			for(auto it2 : nodes[it]) minimum = min(minimum, find_mn(it2));
			candidates.pb({{it, minimum.se}, minimum.fi});
			for(auto it2 : nodes[it]) remaining.insert(it2);
			//cout << "OKOK " <<  it << " " << minimum.se << " " << minimum.fi << "\n";
		}
		//for(auto it : candidates) cout << it.fi.fi << " " << it.fi.se << " " << it.se << "\n";
		//continue;
		//if(itr == 2) continue;
		for(auto it : candidates) merge(it.fi.fi, it.fi.se, it.se);
		//cout << nodes[rt[1]].size() << " " << cnt << "\n";
	}
	cout << answer << "\n";
}

signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	//freopen("kek.inp", "r", stdin);
	//freopen("kek.out", "w", stdout);
	int t;
	cin >> t;
	while(t--) process();
}
#endif

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 15868kb

input:

3
5 3
1 2 5
2 3 4
1 5 0
5 0
5 4
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 5 1000000000

output:

4
4
1000000003

result:

ok 3 number(s): "4 4 1000000003"

Test #2:

score: -100
Runtime Error

input:

16
1000000000 0
447 99681
1 2 1000000000
1 3 1000000000
2 3 1000000000
1 4 1000000000
2 4 1000000000
3 4 1000000000
1 5 1000000000
2 5 1000000000
3 5 1000000000
4 5 1000000000
1 6 1000000000
2 6 1000000000
3 6 1000000000
4 6 1000000000
5 6 1000000000
1 7 1000000000
2 7 1000000000
3 7 1000000000
4 7 ...

output:


result: