线段树优化建图模板 Legacy CodeForces - 786B

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define lowbit(x) x&(-x)
#define REP(i,a,n) for(int i=a;i<=(n);i++)
typedef long long ll;
typedef pair P;
const int maxn = 1e5 + 10;
const int N = 1e6 + 10;
const int M = 4e6 + 10;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
int head[N], ver[M], Next[M];
ll edge[M];
int tot;
void add(int x, int y, ll val)
{
	ver[++tot] = y, edge[tot] = val, Next[tot] = head[x], head[x] = tot;
}
ll d[N];
void dijkstra(int s)
{
	memset(d, inf, sizeof(d));
	d[s] = 0;
	priority_queue, greater

> que; que.push(P(d[s], s)); while (!que.empty()) { P p = que.top(); que.pop(); int u = p.second; if (d[u] < p.first) { continue; } for (int i = head[u]; i; i = Next[i]) { int v = ver[i]; if (d[v] > d[u] + edge[i]) { d[v] = d[u] + edge[i]; que.push(P(d[v], v)); } } } } int cnt; struct node { int l, r; }; struct Segmenttree { int id[maxn << 2]; node t[maxn << 2]; void build(int p, int l, int r, bool up) { id[p] = ++cnt; t[p].l = l, t[p].r = r; if (l == r) { int u = id[p]; int v = l; if (up) swap(u, v); add(u, v, 0); return; } int mid = l + r >> 1; build(p << 1, l, mid, up); build(p << 1 | 1, mid + 1, r, up); int u = id[p]; int v = id[p << 1]; if (up) swap(u, v); add(u, v, 0); u = id[p]; v = id[p << 1 | 1]; if (up) swap(u, v); add(u, v, 0); } void addedge(int p, int l, int r, int x, int w, int up) { if (l <= t[p].l&&t[p].r <= r) { int u = id[p]; int v = x; if (up) swap(u, v); add(u, v, w); return; } int mid = t[p].l + t[p].r >> 1; if (l <= mid) addedge(p << 1, l, r, x, w, up); if (r > mid) addedge(p << 1 | 1, l, r, x, w, up); } }down, up; signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int n, q, s; cin >> n >> q >> s; cnt = n; down.build(1, 1, n, false); up.build(1, 1, n, true); while (q--) { int t, u, l, r, w; cin >> t; if (t == 1) { int v; cin >> u >> v >> w; add(u, v, w); } else { cin >> u >> l >> r >> w; if (t == 2) { down.addedge(1, l, r, u, w, true); } else { up.addedge(1, l, r, u, w, false); } } } dijkstra(s); for (int i = 1; i <= n; i++) { if (d[i] == INF) cout << "-1"; else cout << d[i]; cout << " "; } return 0; }

 

你可能感兴趣的:(线段树&&主席树,图论模板)