QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#76763#5506. Hyperloopheno239AC ✓4763ms55844kbC++1711.3kb2023-02-12 10:05:392023-02-12 10:05:42

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-02-12 10:05:42]
  • 评测
  • 测评结果:AC
  • 用时:4763ms
  • 内存:55844kb
  • [2023-02-12 10:05:39]
  • 提交

answer

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
//constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	//if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
//mod should be <2^31
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= (int)mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += (int)mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 2;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
using ld = long double;
//typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-10;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
	if (loc >= v.size())v.resize(loc + 1, 0);
	v[loc] += val;
}
/*const int mn = 2000005;
bool isp[mn];
vector<int> ps;
void init() {
	fill(isp + 2, isp + mn, true);
	for (int i = 2; i < mn; i++) {
		if (!isp[i])continue;
		ps.push_back(i);
		for (int j = 2 * i; j < mn; j += i) {
			isp[j] = false;
		}
	}
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	if (res == st.begin())return st.end();
	res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	return res;
}
using mP = pair<modint, modint>;
mP operator+(mP a, mP b) {
	return { a.first + b.first,a.second + b.second };
}
mP operator+=(mP& a, mP b) {
	a = a + b; return a;
}
mP operator-(mP a, mP b) {
	return { a.first - b.first,a.second - b.second };
}
mP operator-=(mP& a, mP b) {
	a = a - b; return a;
}
LP operator+(LP a, LP b) {
	return { a.first + b.first,a.second + b.second };
}
LP operator+=(LP& a, LP b) {
	a = a + b; return a;
}
LP operator-(LP a, LP b) {
	return { a.first - b.first,a.second - b.second };
}
LP operator-=(LP& a, LP b) {
	a = a - b; return a;
}

mt19937 mt(time(0));

const string drul = "DRUL";
string senw = "SENW";
//DRUL,or SENW
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
//-----------------------------------------


bool isp(int x) {
	if (x == 1)return false;
	for (int i = 2; i * i <= x; i++) {
		if (x % i == 0)return false;
	}
	return true;
}
//1.1*10^9だと2.2*10^9がintでoverflowする
mt19937 mtle(time(0));
uniform_int_distribution<> udle(900000000, 1000000000);
int findmodp() {
	int le = udle(mtle);
	while (!isp(le))le++;
	return le;
}
using ar = array<int, 2>;


ar ms;
ar ts;

ar rhs[100005];
ar oricnt[100005];
void init() {
	rep(i, 2) {
		ms[i] = findmodp();
		ts[i] = findmodp();
		while (ts[i] % ms[i] == 0) {
			ts[i] = findmodp();
		}
		ts[i] %= ms[i];
	}
	rhs[0] = { 1,1 };
	rep(i, 100005) {
		rep(j, 2) {
			rhs[i + 1][j] = (ll)rhs[i][j] * ts[j] % ms[j];
		}
	}
	oricnt[0] = { 0,0 };
	for (int i = 1; i < 100005; i++) {
		rep(j, 2) {
			oricnt[i][j] = (oricnt[i - 1][j] + rhs[i][j]) % ms[j];
		}
	}
	//cout << ts[0] << " " << ts[1] << "\n";
}
ar operator*(ar a, ll v) {
	rep(j, 2) {
		ll adv = v % ms[j];
		if (adv < 0)adv += ms[j];
		a[j] = (ll)a[j] * adv % ms[j];
	}
	return a;
}
ar operator*(ar a, ar b) {
	rep(j, 2) {
		a[j] = (ll)a[j] * b[j] % ms[j];
	}
	return a;
}
ar operator+(ar a, ar b) {
	rep(j, 2) {
		a[j] += b[j]; if (a[j] >= ms[j])a[j] -= ms[j];
	}
	return a;
}
ar operator-(ar a, ar b) {
	rep(j, 2) {
		a[j] -= b[j]; if (a[j] < 0)a[j] += ms[j];
	}
	return a;
}

int tmp;
struct Data {
	ar val;
	int cnt;
};
Data merge(Data a, Data b) {
	Data res;
	res.val = a.val + b.val * rhs[a.cnt];
	res.cnt = a.cnt + b.cnt;
	return res;
}
Data e = { {0,0},0 };
const int LIM_N = 1900000;
Data node[LIM_N];
int nex[LIM_N][2];
int mem[1 << 17];


void init_seg() {
	mem[0] = 0;
	int sz = (1 << 16);
	rep(i, 2 * sz - 1) {
		node[i] = e;
		rep(j, 2) {
			nex[i][j] = 2 * i + 1 + j;
		}
	}
	tmp = 2 * sz - 1;
}
int add(int x, int k, int l = 0, int r = -1) {
	if (r < 0)r = (1 << 16);
	if (x < l || r <= x)return k;
	if (l == x && x + 1 == r) {
		int c = node[k].cnt;
		c++;
		node[tmp].val = oricnt[c] * x;
		node[tmp].cnt = c;
		int res = tmp;
		tmp++;
		return res;
	}
	else {
		int nl = nex[k][0];
		int nr = nex[k][1];
		int vl = add(x, nl, l, (l + r) / 2);
		int vr = add(x, nr, (l + r) / 2, r);
		node[tmp] = merge(node[vl], node[vr]);
		nex[tmp][0] = vl, nex[tmp][1] = vr;
		int res = tmp;
		tmp++;
		return res;
	}
	return -1;
}
void addval(int x, int num, int k, int l = 0, int r = -1) {
	if (r < 0)r = (1 << 16);
	if (x < l || r <= x)return;
	if (l == x && x + 1 == r) {
		node[k].cnt += num;
		node[k].val = oricnt[node[k].cnt] * x;
	}
	else {
		int nl = nex[k][0];
		int nr = nex[k][1];
		//cout << "? " << k << " " << nl << " " << nr << "\n";
		addval(x, num, nl, l, (l + r) / 2);
		addval(x, num, nr, (l + r) / 2, r);
		node[k] = merge(node[nl], node[nr]);
	}
}
Data query(int len, int k, int l = 0, int r = -1) {
	if (r < 0)r = (1 << 16);
	Data res;
	if (r - l == 1) {
		res.val = oricnt[len] * l;
		res.cnt = len;
	}
	else {
		int vl = nex[k][0];
		int vr = nex[k][1];
		if (node[vr].cnt >= len) {
			res = query(len, vr, (l + r) / 2, r);
		}
		else {
			Data res2 = node[vr];
			Data res1 = query(len - res2.cnt, vl, l, (l + r) / 2);
			res = merge(res1, res2);
		}
	}
	return res;
}
int getcol(int len, int k, int l = 0, int r = -1) {
	if (len == node[k].cnt)return -1;
	if (r < 0)r = (1 << 16);
	int res;
	if (r - l == 1) {
		res = l;
	}
	else {
		int vl = nex[k][0];
		int vr = nex[k][1];
		if (node[vr].cnt > len) {
			res = getcol(len, vr, (l + r) / 2, r);
		}
		else {
			res = getcol(len - node[vr].cnt, vl, l, (l + r) / 2);
		}
	}
	return res;
}


struct edge {
	int to, cost;
};
void solve() {
	init_seg();
	int n, m; cin >> n >> m;
	vector<vector<edge>> G(n);
	rep(i, m) {
		int a, b; cin >> a >> b; a--; b--;
		int c; cin >> c;
		G[a].push_back({ b,c });
		G[b].push_back({ a,c });
	}
	vector<ll> dist(n, INF);
	priority_queue<LP, vector<LP>, greater<LP>> q;
	dist[0] = 0;
	q.push({ 0,0 });
	vector<int> ids;
	while (!q.empty()) {
		LP p = q.top(); q.pop();
		int id = p.second;
		ll d = p.first;
		if (dist[id] < d)continue;
		ids.push_back(id);
		for (edge e : G[id]) {
			ll nd = d + e.cost;
			if (nd < dist[e.to]) {
				dist[e.to] = nd;
				q.push({ nd,e.to });
			}
		}
	}
	//coutarray(dist);
	vector<int> par(n);
	for (int id : ids) {
		if (id == 0)continue;
		vector<edge> pres;
		for (edge e : G[id]) {
			if (dist[e.to] + e.cost == dist[id]) {
				pres.push_back(e);
			}
		}
		//cout << id << " " << pres.size() << "\n";
		edge chk = pres[0];
		for (int i = 1; i < pres.size(); i++) {
			edge e = pres[i];
			int len = min(node[mem[chk.to]].cnt, node[mem[e.to]].cnt) + 1;
			int le = 0, ri = len + 1;
			while (ri - le > 1) {
				int mid = (le + ri) / 2;
				addval(chk.cost, 1, mem[chk.to]);
				Data dl = query(mid, mem[chk.to]);
				addval(chk.cost, -1, mem[chk.to]);
				addval(e.cost, 1, mem[e.to]);
				Data dr = query(mid, mem[e.to]);
				addval(e.cost, -1, mem[e.to]);
				//cout << "? " << id << " " << chk.to << " " << e.to << " " << mid << "\n";
				//rep(j, 2)cout << dl.val[j] << " "; cout << "\n";
				//rep(j, 2)cout << dr.val[j] << " "; cout << "\n";
				if (dl.val == dr.val) {
					le = mid;
				}
				else {
					ri = mid;
				}
			}
			//cout << "? " << id << " " << chk.to << " " << e.to << " " << le << "\n";
			addval(chk.cost, 1, mem[chk.to]);
			int vl = getcol(le, mem[chk.to]);
			addval(chk.cost, -1, mem[chk.to]);
			addval(e.cost, 1, mem[e.to]);
			int vr = getcol(le, mem[e.to]);
			addval(e.cost, -1, mem[e.to]);
			//cout << "? " << id << " " << chk.to << " " << e.to << " " << le << " " << vl << " " << vr << "\n";
			if (vl < vr)chk = e;
		}

		mem[id] = add(chk.cost, mem[chk.to]);
		//cout << id << " " << mem[id] << "\n";
		par[id] = chk.to;
		if (id == n - 1)break;
	}
	vector<int> ans;
	int cur = n - 1;
	while (cur != 0) {
		ans.push_back(cur); cur = par[cur];
	}
	ans.push_back(0);
	reverse(all(ans));
	rep(i, ans.size())ans[i]++;
	cout << ans.size() << "\n";
	coutarray(ans);
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	init();
	//expr();
	//while(true)
	int t; cin >> t; rep(i, t)
		solve();
	return 0;
}




详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 7584kb

input:

2
4 6
1 2 1
1 3 2
2 3 1
2 4 2
3 4 1
1 4 4
6 11
1 2 9
2 3 12
3 4 3
4 5 5
5 6 10
6 1 22
2 4 9
3 6 1
4 6 5
2 5 2
3 5 8

output:

3
1 2 4
5
1 2 5 3 6

result:

ok correct (2 test cases)

Test #2:

score: 0
Accepted
time: 533ms
memory: 7988kb

input:

600
320 1547
204 81 13768
232 97 9939
97 249 3719
201 109 14322
183 132 40881
142 143 1
275 186 24548
18 236 7907
30 317 11845
131 130 1
311 300 11704
141 92 41925
174 191 32128
119 120 1
184 183 1
310 309 1
283 270 25477
233 141 36076
212 92 13770
307 110 40656
218 137 14033
180 85 41892
200 199 44...

output:

184
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 89 90 91 92 93 94 95 96 97 98 99 100 101 102 10...

result:

ok correct (600 test cases)

Test #3:

score: 0
Accepted
time: 4763ms
memory: 53324kb

input:

4
100000 220000
48940 43355 42347
77914 77913 1
45236 82683 42904
22563 16038 34866
81537 81538 43088
49803 51485 25497
63071 25523 14336
44102 39850 43782
13607 92386 16724
98711 73651 46840
17775 16801 28765
5757 98829 13508
85095 48444 1
9198 43003 32678
14461 14462 1
20245 48742 18138
89120 8911...

output:

35000
1 24721 24696 24717 24804 24757 24988 24231 25030 24601 94061 24443 24448 24563 25096 43056 43055 43054 43053 43052 43051 43050 43049 43048 43047 43046 43045 43044 43043 43042 43041 43040 43039 43038 43037 43036 43035 43034 43033 43032 43031 43030 43029 43028 43027 43026 43025 43024 43023 4302...

result:

ok correct (4 test cases)

Test #4:

score: 0
Accepted
time: 4552ms
memory: 55844kb

input:

4
100000 160000
5533 94547 28459
14992 20984 20548
70133 92512 27510
9013 9012 304
13621 40571 47787
305 306 262
6987 6988 135
16234 16992 40656
26246 49196 27701
19103 60272 44055
91532 91531 38290
70778 68341 35147
32524 32523 13
85786 50300 40970
49277 29735 13942
43446 34519 42455
77623 17031 34...

output:

316
1 2 3 4 5 6 97410 97409 26434 26435 26436 26437 98883 1370 1369 1368 92157 92158 4815 4816 4817 4818 50181 16985 89607 89608 24674 16979 16980 38428 13232 13233 13234 13664 13663 95009 7166 7169 7168 7163 24798 24799 11787 31031 53551 7309 7310 35482 7933 25067 32714 32715 44194 2068 72216 79593...

result:

ok correct (4 test cases)

Test #5:

score: 0
Accepted
time: 1984ms
memory: 54328kb

input:

4
100000 160000
89517 25671 43802
21059 21058 1
35299 91834 43615
53383 53382 1
27213 39161 17202
10715 4050 30342
44100 44099 1
24162 28648 7378
19022 23084 37734
66056 97934 14651
31566 89391 23215
91038 91037 1
47695 47696 6099
99142 99143 1
83908 73654 15060
15551 22001 8896
55190 55189 1
26536 ...

output:

632
1 94652 94659 94664 1697 31258 31267 31276 31231 99694 31227 31190 31223 91851 2489 2480 2483 98560 2507 2512 2515 2532 2529 99815 71980 74130 74129 99693 84670 84671 71536 30302 30301 30300 30299 30298 30297 30296 30295 30294 30293 30292 30291 30290 30289 30288 30287 30286 30285 26878 35089 708...

result:

ok correct (4 test cases)