Submission #1112373

#TimeUsernameProblemLanguageResultExecution timeMemory
1112373Muaath_5Bridges (APIO19_bridges)C++17
0 / 100
3056 ms20392 KiB
// Problem: E - Bridges
// Contest: Virtual Judge - Square root tech
// URL: https://vjudge.net/contest/671583#problem/E
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// 
// By Muaath Alqarni
// Blog: https://muaath5.githib.io/blog
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
using namespace std;

const int N = 5e4+1, M = 1e5+1, SQ = 317;

int par[N], cnt[N];
vector<pair<int*, int>> history;
void init() {
	history.clear();
	for (int i = 1; i < N; i++)
		par[i] = i, cnt[i] = 1;
}
int root(int x) {return par[x]==x?x:par[x];}
void change(int &a, int b) {
	history.push_back({&a, a});
	a = b;
}
bool merge(int u, int v) {
	u = root(u), v = root(v);
	if (u == v)
		return false;
	if (cnt[u] < cnt[v]) swap(u, v);
	change(par[v], u);
	change(cnt[u], cnt[u]+cnt[v]);
	change(cnt[v], 0);
	return true;
}
void rollback(int state) {
	while (history.size() > state) {
		auto [ptr, val] = history.back();
		*ptr = val;
		history.pop_back();
	}
}

struct Edge {
	int idx, u, v, w;
} edges[M];
struct Query {
	int idx, type, x, y, ans;
} qrs[M];

int n, m, q;

int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		edges[i].idx = i;
		cin >> edges[i].u >> edges[i].v >> edges[i].w;
	}
	cin >> q;
	for (int i = 0; i < q; i++) {
		qrs[i].idx = i;
		cin >> qrs[i].type >> qrs[i].x >> qrs[i].y;
	}
	
	vector<bool> isextra(m+1);
	for (int ttt = 0; ttt < q; ttt++) {
		if (ttt%SQ == 0) {
			// reset dsu
			init();
			
			vector<vector<int>> upds(m+1);
			
			// prepare extra edges
			vector<Query> queries;
			for (int j = ttt; j < min(q, ttt+SQ); j++)
				if (qrs[j].type == 2)
					queries.push_back(qrs[j]);
				else {
					upds[qrs[j].x].push_back(j);
					isextra[qrs[j].x] = true;
				}
					
			
			// put edges in sorted order
			vector<Edge> extra;
			vector<Edge> mugraph;
			for (int i = 1; i <= m; i++) {
				if (!isextra[i])
					mugraph.push_back(edges[i]);
				else
					extra.push_back(edges[i]);
			}
			
			sort(mugraph.begin(), mugraph.end(),
				[](Edge x, Edge y){ return x.w > y.w; });
			sort(queries.begin(), queries.end(),
				[](Query x, Query y){ return x.y > y.y; });
			
			int mu_idx = 0;
			for (auto qqq : queries) {
				while (mu_idx < mugraph.size() && mugraph[mu_idx].w >= qqq.y) {
					merge(mugraph[mu_idx].u, mugraph[mu_idx].v);
					mu_idx++;
				}
				cerr << "Processed " << qqq.idx << endl;
	
				int state = history.size();
				for (auto ee : extra) {
					if (upds[ee.idx][0] < qqq.idx)
						ee.w = qrs[*prev(lower_bound(upds[ee.idx].begin(), upds[ee.idx].end(), qqq.idx))].y;
					if (ee.w >= qqq.y)
						merge(ee.u, ee.v);
				}
				
				qrs[qqq.idx].ans = cnt[root(qqq.x)];
				
				rollback(state);
			}
			
			// update the edges with their last value:
			for (int j = ttt; j < min(q, ttt+SQ); j++)
				if (qrs[j].type == 1)
					edges[qrs[j].x].w = qrs[j].y;
		}
		
		if (qrs[ttt].type == 2)
			cout << qrs[ttt].ans << '\n';
	}
}

Compilation message (stderr)

bridges.cpp: In function 'void rollback(int)':
bridges.cpp:42:24: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<int*, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   42 |  while (history.size() > state) {
      |         ~~~~~~~~~~~~~~~^~~~~~~
bridges.cpp: In function 'int main()':
bridges.cpp:108:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Edge>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  108 |     while (mu_idx < mugraph.size() && mugraph[mu_idx].w >= qqq.y) {
      |            ~~~~~~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...