QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#537#331503#7415. Fast Spanning TreeDualqwqDualqwqFailed.2024-02-18 15:07:342024-02-18 15:07:34

Details

Extra Test:

Invalid Input

input:

1 2
1
1 2 1
2 3 1

output:


result:

FAIL Integer parameter [name=b_i] equals to 2, violates the range [1, 1] (stdin, line 3)

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#331503#7415. Fast Spanning TreeDualqwqAC ✓942ms48516kbC++173.8kb2024-02-18 12:21:532024-02-18 12:21:53

answer

#include <bits/stdc++.h>
using namespace std;

namespace FastIO {
	#define iL (1 << 20)
	char ibuf[iL],*iS = ibuf + iL,*iT = ibuf + iL;
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread(ibuf,1,iL,stdin),iS == iT ? EOF : *iS++) : *iS++)
	template<typename T>
	inline void read(T &a) {
		char ch;int sign = 0;
		for(ch = gc();!isdigit(ch);ch = gc())
			if(ch == '-') sign = 1;
		a = ch & 15;
		for(ch = gc();isdigit(ch);ch = gc())
			a = (a << 3) + (a << 1) + (ch & 15);
		if(sign) a = -a;
	}
	char Out[iL],*iter = Out;
	#define flush() fwrite(Out,1,iter - Out,stdout),iter = Out
	template<typename T>
	inline void write(T x,char end = '\n') {
		int c[40],l = 0;if(x < 0) *iter++ = '-',x = -x;
		do c[++l] = x % 10,x /= 10; while(x);
		while(l) *iter++ = c[l--] + '0';
		*iter++ = end;flush();
	}
	#undef iL
	#undef gc
	#undef flush
}
using namespace FastIO;


const int N = 3e5 + 5,Sz = N * 45;
typedef long long ll;
#define FI first
#define SE second
#define mkp make_pair
int n,m,w[N];
int A[N],B[N],pw[N],wlim[N]; // lim / 2 ceil

int ufs[N],sze[N];
ll Dec[N],sumw[N];
int find(int x) { return ufs[x] == x ? x : ufs[x] = find(ufs[x]);}
// set<pair<ll,int> > warn[N];
// map<int,ll> valw[N];

int lc[Sz],rc[Sz],dis[Sz],rt[N],tot = 0;
pair<ll,int> val[Sz];

int Merge(int x,int y) {
	if(!x || !y) return x + y;
	if(val[x].FI > val[y].FI) swap(x,y);
	// printf("x,y:%d,%d\n",x,y);
	rc[x] = Merge(rc[x],y);
	if(dis[lc[x]] < dis[rc[x]]) swap(lc[x],rc[x]);
	dis[x] = dis[rc[x]] + 1;
	return x;
}
int bac[Sz],baccnt;
// vector<int> bac;
inline int NewNode() { if(baccnt) return bac[baccnt--]; return ++tot;}
inline void Recyc(int x) { lc[x] = rc[x] = dis[x] = 0;bac[++baccnt] = x;}
inline void Push(int id,ll v1,int v2) {
	int p = NewNode();val[p] = make_pair(v1,v2);
	rt[id] = Merge(rt[id],p);
}
priority_queue<int,vector<int>,greater<int> > edges;

void Rebuild_warn(int x,ll dta) {
	x = find(x);vector<int> V;Dec[x] += dta;
	while(rt[x] && val[rt[x]].FI <= Dec[x]) {
		// cerr << "rt:" << rt[x] << endl;
		int id = val[rt[x]].SE;
		V.push_back(id);int p = rt[x];
		rt[x] = Merge(lc[rt[x]],rc[rt[x]]);
		Recyc(p);
	}
	for(auto id : V) if(find(A[id]) != find(B[id])) {
		int y = find(A[id]) ^ find(B[id]) ^ x;
		wlim[id] = max(0ll,pw[id] - Dec[x] - Dec[y]);
		// printf("dec:%d,%d\n",id,dta);
		if(wlim[id] <= 0) edges.push(id);
		else {
			int v = (wlim[id] + 1) / 2;
			// valw[x][id] = (v + Dec[x]);valw[y][id] = (v + Dec[y]);
			// warn[x].emplace(v + Dec[x],id);
			// warn[y].emplace(v + Dec[y],id);
			Push(x,v + Dec[x],id);Push(y,v + Dec[y],id);
		}
	}
}
void Union(int x,int y) {
	assert(x != y);
	if(sze[x] < sze[y]) swap(x,y);
	ll s1 = sumw[x],s2 = sumw[y];
	Rebuild_warn(x,s2);Rebuild_warn(y,s1);
	sze[x] += sze[y];sumw[x] += sumw[y];
	ufs[y] = x;
	// for(auto [v,id] : warn[y]) {
	// 	if(find(A[id]) == find(B[id])) continue;
	// 	warn[x].emplace(v,id);
	// 	// valw[x][id] = v;
	// }
	// warn[y].clear();//valw[y].clear();
	rt[x] = Merge(rt[x],rt[y]);

}

int main() {
	read(n);read(m);
	for(int i = 1;i <= n;i++)
		read(w[i]),sumw[i] = w[i],sze[i] = 1,ufs[i] = i;
	for(int i = 1;i <= m;i++) {
		read(A[i]);read(B[i]);read(wlim[i]);
		pw[i] = wlim[i];
		int v = (wlim[i] + 1) / 2;
		// warn[A[i]].emplace(v,i);
		// valw[A[i]][i] = v;
		// warn[B[i]].emplace(v,i);
		// valw[B[i]][i] = v;
		Push(A[i],v,i);Push(B[i],v,i);
	}
	// cerr << "done" << endl;
	for(int i = 1;i <= n;i++) Rebuild_warn(i,w[i]);
	vector<int> Ans;
	while(!edges.empty()) {
		int id = edges.top();edges.pop();
		// cerr << id << endl;
		int x = A[id],y = B[id];
		x = find(x);y = find(y);
		if(x == y) continue;
		Union(x,y);
		Ans.push_back(id);
	}
	printf("%d\n",Ans.size());
	for(auto i : Ans) write(i,' ');
	printf("\n");
	return 0;
}