RE 求助
查看原帖
RE 求助
214437
IntrepidStrayer楼主2021/2/26 15:50

RE #11,n=100,m=197n=100,m=197,应该不是数组开小问题。也不是主席树 l>rl>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;
}
2021/2/26 15:50
加载中...