제출 #140547

#제출 시각아이디문제언어결과실행 시간메모리
140547luciocf다리 (APIO19_bridges)C++14
13 / 100
421 ms3420 KiB
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;

const int maxn = 5e4+10;
const int maxm = 1e5+10;
const int inf = 1e9+10;

struct Edge
{
	int u, v, w;
} edge[maxm], aux[maxm];

struct Op
{
	int u, w, ind;
} query[maxm];

int n, m, q;
int tot;

int ans[maxm];

int pai[maxn], peso[maxn];

int tree[4*maxn];

vector<pii> grafo[maxn];

bool comp(Edge a, Edge b) {return a.w > b.w;}
bool comp2(Op a, Op b) {return a.w > b.w;}

void init(void)
{
	for (int i = 1; i <= n; i++)
	{
		pai[i] = i, peso[i] = 1;
		grafo[i].clear();
	}
}

int Find(int x)
{
	if (pai[x] == x) return x;
	return pai[x] = Find(pai[x]);
}

void Join(int x, int y)
{
	x = Find(x), y = Find(y);
	if (x == y) return;

	if (peso[x] < peso[y]) swap(x, y);

	pai[y] = x, peso[x] += peso[y];
}

void get_mst(void)
{
	init();

	for (int i = 1; i <= m; i++)
		aux[i] = edge[i];

	sort(aux+1, aux+m+1, comp);

	for (int i = 1; i <= m; i++)
	{
		if (Find(aux[i].u) != Find(aux[i].v))
		{
			Join(aux[i].u, aux[i].v);

			grafo[aux[i].u].push_back({aux[i].v, aux[i].w});
			grafo[aux[i].v].push_back({aux[i].u, aux[i].w});
		}
	}
}

void dfs(int u, int p, int w)
{
	tot++;

	for (auto v: grafo[u])
		if (v.first != p && v.second >= w)
			dfs(v.first, u, w);
}

void build(int node, int l, int r)
{
	if (l == r)
	{
		tree[node] = edge[l].w;
		return;
	}

	int mid = (l+r)>>1;

	build(2*node, l, mid); build(2*node+1, mid+1, r);

	tree[node] = min(tree[2*node], tree[2*node+1]);
}

void upd(int node, int l, int r, int pos, int v)
{
	if (l == r)
	{
		tree[node] = v;
		return;
	}

	int mid = (l+r)>>1;

	if (pos <= mid) upd(2*node, l, mid, pos, v);
	else upd(2*node+1, mid+1, r, pos, v);

	tree[node] = min(tree[2*node], tree[2*node+1]);
}

int busca1(int node, int l, int r, int pos, int v)
{
	if (tree[node] >= v) return inf;

	if (l == r) return (l > pos ? l : inf);

	int mid = (l+r)>>1;

	if (mid <= pos || tree[2*node] >= v) return busca1(2*node+1, mid+1, r, pos, v);

	int p1 = busca1(2*node, l, mid, pos, v);
	if (p1 != inf) return p1;

	return busca1(2*node+1, mid+1, r, pos, v);
}

int busca2(int node, int l, int r, int pos, int v)
{
	if (tree[node] >= v) return inf;

	if (l == r) return (l < pos ? l : inf);

	int mid = (l+r)>>1;

	if (mid+1 >= pos || tree[2*node+1] >= v) return busca2(2*node, l, mid, pos, v);

	int p1 = busca2(2*node+1, mid+1, r, pos, v);
	if (p1 != inf) return p1;

	return busca2(2*node, l, mid, pos, v);
}

void solve_small(void)
{
	for (int i = 1; i <= q; i++)
	{
		int op;
		scanf("%d", &op);

		if (op == 1)
		{
			int ind, w;
			scanf("%d %d", &ind, &w);

			edge[ind].w = w;
		}
		else
		{
			int u, w;
			scanf("%d %d", &u, &w);

			get_mst();

			tot = 0;
			dfs(u, 0, w);

			printf("%d\n", tot);
		}
	}
}

void solve_chain(void)
{
	build(1, 1, n-1);

	for (int i = 1; i <= q; i++)
	{
		int op;
		scanf("%d", &op);

		if (op == 1)
		{
			int ind, w;
			scanf("%d %d", &ind, &w);

			upd(1, 1, n-1, ind, w);
		}
		else
		{
			int u, w;
			scanf("%d %d", &u, &w);

			int r = busca1(1, 1, n-1, u, w);
			int l = busca2(1, 1, n-1, u, w);

			int ans = (r == inf ? n-u : r-u);

			ans += (l == inf ? u-1 : u-l-1);

			printf("%d\n", ans+1);
		}
	}
}

void solve_two(void)
{
	for (int i = 1; i <= q; i++)
	{
		int fuckyou;
		scanf("%d", &fuckyou);

		scanf("%d %d", &query[i].u, &query[i].w);
		query[i].ind = i;
	}

	sort(edge+1, edge+m+1, comp);
	sort(query+1, query+q+1, comp2);

	init();

	int p = 1;

	for (int i = 1; i <= q; i++)
	{
		while (edge[p].w >= query[i].w)
		{
			Join(edge[p].u, edge[p].v);
			p++;
		}

		ans[query[i].ind] = peso[Find(query[i].u)];
	}

	for (int i = 1; i <= q; i++)
		printf("%d\n", ans[i]);
}

int main(void)
{
	scanf("%d %d", &n, &m);

	bool ok = 1;
	if (m != n-1) ok = 0;

	for (int i = 1; i <= m; i++)
	{
		int u, v, w;
		scanf("%d %d %d", &u, &v, &w);

		edge[i] = {u, v, w};

		if (v != i+1 || u != i) ok = 0;
	}

	scanf("%d", &q);
	
	if (n <= 1000 && m <= 1000 && q <= 10000)
	{
		solve_small();
		return 0;
	}

	solve_chain();
}

컴파일 시 표준 에러 (stderr) 메시지

bridges.cpp: In function 'int main()':
bridges.cpp:252:7: warning: variable 'ok' set but not used [-Wunused-but-set-variable]
  bool ok = 1;
       ^~
bridges.cpp: In function 'void solve_small()':
bridges.cpp:158:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &op);
   ~~~~~^~~~~~~~~~~
bridges.cpp:163:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    scanf("%d %d", &ind, &w);
    ~~~~~^~~~~~~~~~~~~~~~~~~
bridges.cpp:170:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    scanf("%d %d", &u, &w);
    ~~~~~^~~~~~~~~~~~~~~~~
bridges.cpp: In function 'void solve_chain()':
bridges.cpp:189:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &op);
   ~~~~~^~~~~~~~~~~
bridges.cpp:194:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    scanf("%d %d", &ind, &w);
    ~~~~~^~~~~~~~~~~~~~~~~~~
bridges.cpp:201:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    scanf("%d %d", &u, &w);
    ~~~~~^~~~~~~~~~~~~~~~~
bridges.cpp: In function 'void solve_two()':
bridges.cpp:220:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &fuckyou);
   ~~~~~^~~~~~~~~~~~~~~~
bridges.cpp:222:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d", &query[i].u, &query[i].w);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp: In function 'int main()':
bridges.cpp:250:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d", &n, &m);
  ~~~~~^~~~~~~~~~~~~~~~~
bridges.cpp:258:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d %d", &u, &v, &w);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:265:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &q);
  ~~~~~^~~~~~~~~~
#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...