RE #11,n=100,m=197,应该不是数组开小问题。也不是主席树 l>r
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
inline ll max(ll x, ll y) {return x > y ? x : y;}
inline ll min(ll x, ll y) {return x < y ? x : y;}
inline ll _abs(ll x) {return x < 0 ? -x : x;}
inline void swap(int &x, int &y) {x ^= y ^= x ^= y;}
#define rei register int
#define rep(i, l, r) for(rei i = l, i##end = r; i <= i##end; ++i)
#define per(i, r, l) for(rei i = r, i##end = l; i >= i##end; --i)
#define ci const int
char inputbuf[1 << 23], *p1 = inputbuf, *p2 = inputbuf;
#define getchar() (p1 == p2 && (p2 = (p1 = inputbuf) + fread(inputbuf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0; char ch = getchar(); bool f = true;
for(; ch < '0' || ch > '9'; ch = getchar())
if(ch == '-') f = false;
for(; ch >= '0' && ch <= '9'; ch = getchar())
res = res * 10 + (ch ^ 48);
return f ? res : -res;
}
const int N = 1e5 + 15, M = 1e7 + 5, HgS = 1e9 + 7, B = 3;
int base[N * 18 + 1], n, m, buc[N * 18 + 1], pow2[N * 18 + 1], lim;
namespace _ {
int lc[M], rc[M], l0[M], r0[M], tot = 0;
ll h[M];
bool tag[M];
inline int cr() {
tot ++ ;
lc[tot] = rc[tot] = l0[tot] = r0[tot] = h[tot] = tag[tot] = 0;
return tot;
}
inline void upd(int p, int rlen) {
l0[p] = l0[lc[p]] < 1e9 ? l0[lc[p]] : l0[rc[p]];
r0[p] = r0[rc[p]] < 1e9 ? r0[rc[p]] : r0[lc[p]];
h[p] = (1ll * base[rlen] * h[lc[p]] + h[rc[p]]) % HgS;
}
inline void stag(int p, int l, int r) {
tag[p] = 1;
h[p] = 0;
l0[p] = l;
r0[p] = r;
}
inline void push_down(int p, int l, int r, int mid) {
if(!lc[p]) lc[p] = cr();
if(!rc[p]) rc[p] = cr();
if(!tag[p]) return ;
stag(lc[p], l, mid);
stag(rc[p], mid + 1, r);
tag[p] = 0;
}
int build(int l, int r) {
int p = cr();
l0[p] = l;
r0[p] = r;
if(l == r) return p;
int mid = l + r >> 1;
lc[p] = build(l, mid);
rc[p] = build(mid + 1, r);
return p;
}
int init1(int l, int r) {
int p = cr();
l0[p] = 1e9;
r0[p] = 1e9;
if(l == r) return h[p] = 1, p;
int mid = l + r >> 1;
lc[p] = init1(l, mid);
rc[p] = init1(mid + 1, r);
upd(p, r - mid);
return p;
}
int modify(int rt, int l, int r, ci &tl, ci &tr, ci &x) {
int p = cr();
if(tl <= l && r <= tr) {
if(x) h[p] = 1, l0[p] = r0[p] = 1e9;
else stag(p, l, r);
return p;
}
int mid = l + r >> 1;
push_down(rt, l, r, mid);
lc[p] = tl <= mid ? modify(lc[rt], l, mid, tl, tr, x) : lc[rt];
rc[p] = mid < tr ? modify(rc[rt], mid + 1, r, tl, tr, x) : rc[rt];
upd(p, r - mid);
return p;
}
int find0(int p, int l, int r, ci &tr) {
if(l > r) return 1e9;
if(l == r || r <= tr) return r0[p];
int mid = l + r >> 1, res;
push_down(p, l, r, mid);
if(tr <= mid) return find0(lc[p], l, mid, tr);
res = find0(rc[p], mid + 1, r, tr);
return res < 1e9 ? res : find0(lc[p], l, mid, tr);
}
ll dfs(int p, int l, int r) {
if(!p) return 0;
if(l == r) return 1ll * pow2[lim - l] * h[p] % HgS;
int mid = l + r >> 1;
push_down(p, l, r, mid);
return (dfs(lc[p], l, mid) + dfs(rc[p], mid + 1, r)) % HgS;
}
inline int add(int p, int i) {
i = lim - i + 1;
int pos0 = find0(p, 1, lim, i);
int rt1 = modify(p, 1, lim, pos0, pos0, 1);
return pos0 < i ? modify(rt1, 1, lim, pos0 + 1, i, 0) : rt1;
}
inline bool cmp(int p1, int p2, int l, int r) {
if(l == r) return h[p1] < h[p2];
int mid = l + r >> 1, res;
push_down(p1, l, r, mid);
push_down(p2, l, r, mid);
if(h[lc[p1]] == h[lc[p2]]) return cmp(rc[p1], rc[p2], mid + 1, r);
return cmp(lc[p1], lc[p2], l, mid);
}
}
using _ :: cmp;
using _ :: add;
using _ :: tot;
int dis[N], num[N], pre[N], to[N << 1], nxt[N << 1], len[N << 1], head[N], ecnt, s, t;
bool vis[N];
struct node {
int i;
inline bool operator < (const node &x) const {
return !cmp(dis[i], dis[x.i], 1, lim);
}
} ;
priority_queue <node> Q;
inline void add(int x, int y, int z) {
to[++ ecnt] = y;
len[ecnt] = z;
nxt[ecnt] = head[x];
head[x] = ecnt;
}
void dijkstra() {
int u, v, tmp, ltot = 0;
dis[s] = _ :: build(1, lim);
Q.push((node) { s });
tmp = _ :: init1(1, lim);
rep(i, 1, n) if(i ^ s) dis[i] = tmp;
tmp = 0;
num[s] = 1;
while(Q.size()) {
u = Q.top().i; Q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(rei i = head[u]; i; i = nxt[i]) {
v = to[i];
ltot = tot;
tmp = add(dis[u], len[i]);
if(cmp(tmp, dis[v], 1, lim)) {
dis[v] = tmp;
pre[v] = u;
num[v] = num[u] + 1;
if(!vis[v]) Q.push((node) {v});
} else tot = ltot;
}
}
}
void print(int x) {
if(pre[x]) print(pre[x]);
printf("%d ", x);
}
signed main() {
int x, y, z;
n = read(); m = read();
rep(i, 1, m) {
x = read(); y = read(); z = read() + 1;
add(x, y, z); add(y, x, z);
buc[z] ++ ;
}
s = read(); t = read();
if(!m) {
if(s == t) printf("0\n1\n%d\n", s);
else puts("-1");
return 0;
}
rep(i, 1, 1.75e6)
if(buc[i] > 0) {
lim = i;
if(buc[i] > 1) {
buc[i + 1] += buc[i] >> 1;
buc[i] &= 1;
}
}
lim += 5;
base[0] = pow2[0] = 1;
rep(i, 1, lim) {
pow2[i] = 2ll * pow2[i - 1] % HgS;
base[i] = 1ll * base[i - 1] * B % HgS;
}
dijkstra();
if(num[t]) {
printf("%lld\n%d\n", _ :: dfs(dis[t], 1, lim), num[t]);
print(t);
} else puts("-1");
return 0;
}