CF786B Legacy(线段树优化建图)

sbmqwm, contest: Codeforces Round 406 (Div. 1), problem: (B) Legacy, Accepted

提示:注意内存&&不开long long见祖宗

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
long long n,m,s;
long long blo,op,u;
long long l,r,w,tot;
long long h[8*maxn],intree[4*maxn],outtree[4*maxn],pos[maxn];
long long dis[8*maxn];
bool vis[8*maxn];
struct edge
{
	long long nxt,to,w;
}e[4*maxn*20];
struct node
{
	long long dis,pos;
	bool operator < (const node &nd) const
	{
		return dis>nd.dis;
	}
};
void add(long long x,long long y,long long z)
{
	tot++;
	e[tot].to=y;
	e[tot].nxt=h[x];
	e[tot].w=z;
	h[x]=tot;
}
void build_in(long long l,long long r,long long rt)
{
	if (l == r)
	{
		pos[l]=rt;
		add(rt+blo,rt,0);
		add(rt,rt+blo,0);
		return;
	}
	long long mid=(l+r) >> 1;
	add(rt,2*rt,0);
	build_in(l,mid,2*rt);
	add(rt,2*rt+1,0);
	build_in(mid+1,r,2*rt+1);
}
void build_out(long long l,long long r,long long rt)
{
	if (rt!=1) add(blo+rt,blo+(rt/2),0);
	if (l == r) return;
	long long mid=(l+r) >> 1;
	build_out(l,mid,2*rt);
	build_out(mid+1,r,2*rt+1);
}
void tree_edge(long long nl,long long nr,long long l,long long r,long long rt,long long link_pos,long long ww,long long k)
{
	if (nl<=l && r<=nr)
	{
		if (k == 0) add(link_pos+blo,rt,ww);
		else add(rt+blo,link_pos,ww);
		return;
	}
	long long mid=(l+r) >> 1;
	if (nl<=mid) tree_edge(nl,nr,l,mid,2*rt,link_pos,ww,k);
	if (nr>mid) tree_edge(nl,nr,mid+1,r,2*rt+1,link_pos,ww,k);
}
priority_queue<node> q;
void dijkstra(long long x)
{
	q.push(node{0,x});
	dis[x]=0;
	while (!q.empty())
	{
		long long now=q.top().pos;
		q.pop();
		if (vis[now]) continue;
		vis[now]=true;
		for (long long i=h[now];i;i=e[i].nxt)
		{
			long long y=e[i].to;
			if (dis[y]>dis[now]+e[i].w)
			{
				dis[y]=dis[now]+e[i].w;
				if (!vis[y]) q.push((node){dis[y],y});
			}
		}
	}
}
int main(){
	cin >> n >> m >> s;
	blo=n*4;
	build_in(1,n,1);
	build_out(1,n,1);
	for (long long i=1;i<=m;i++)
	{
		cin >> op >> u;
		if (op == 1)
		{
			cin >> l >> w;
			tree_edge(l,l,1,n,1,pos[u],w,0);
		}
		else if (op == 2)
		{
			cin >> l >> r >> w;
			tree_edge(l,r,1,n,1,pos[u],w,0);
		}
		else if (op == 3)
		{
			cin >> l >> r >> w;
			tree_edge(l,r,1,n,1,pos[u],w,1);
		}
	}
	s=blo+pos[s];
	for (long long i=1;i<=n*8;i++) dis[i]=0x7f7f7f7f7f7f7f7f;
	dijkstra(s);
	for (long long i=1;i<=n;i++)
	{
		if (dis[pos[i]]>=0x7f7f7f7f7f7f7f7f) dis[pos[i]]=-1;
	}
	for (long long i=1;i<=n;i++) cout << dis[pos[i]] << " ";
	return 0;
}
posted @ 2026-03-24 11:47  msjing  阅读(10)  评论(0)    收藏  举报