AT_abc342_e [ABC342E] Last Train 题解

考虑反向建图,然后设 fuf_u 表示 uu 点的答案,fn=+f_n = + \infty。然后 Dijkstra 维护,每次拓展到一个新的点,相当于考虑一些同余相关的问题。容易发现这个东西可以 O(1)O(1) 求出,就做完了。

#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N = 5e5 + 5, MOD = 1e9 + 7, HSMOD = 1610612741, HSMOD2 = 998244353; // Remember to change

int n, m, q, t, a[N];
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());

long long qpow(long long a, long long b)
{
	long long res = 1ll, base = a;
	while (b)
	{
		if (b & 1ll) res = res * base % MOD;
		base = base * base % MOD;
		b >>= 1ll;
	}
	return res;
}

bool isprime(int x)
{
	if (x == 1) return 0;
	for (int i = 2; 1ll * i * i <= x; i++) if (x % i == 0) return 0;
	return 1;
}

namespace FastIo
{
	#define QUICKCIN ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
	int read()
	{
		char ch = getchar();
		int x = 0, f = 1;
		while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
		while (ch == '-')
		{
			f = -f;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9')
		{
			x = (x << 1) + (x << 3) + (ch ^ 48);
			ch = getchar();
		}
		return x * f;
	}
	template<class T>
	void write(T x)
	{
		if (x < 0)
		{
			putchar('-');
			x = -x;
		}
		if (x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
	template<class T>
	void writeln(T x)
	{
		write(x);
		putchar('\n');
	}
}

template<typename T>
class Bit
{
public:
	T lowbit(T x)
	{
		return x & -x;
	}
	T tr[N];
	void add(T x, T y)
	{
		while (x < N)
		{
			tr[x] += y;
			x += lowbit(x);
		}
	}
	T query(T x)
	{
		T sum = 0;
		while (x)
		{
			sum += tr[x];
			x -= lowbit(x);
		}
		return sum;
	}
};

struct Edge
{
	int to, l, k, d, c;
	Edge() = default;
	Edge(int to, int l, int k, int d, int c): to(to),l(l), k(k), d(d), c(c){}
};

vector<Edge> G[N];
int dis[N];

struct Node
{
	int u,d;
	Node(int u,int d):u(u),d(d){}
	Node()=default;
	bool operator<(const Node& g) const
	{
		return d<g.d;
	}
};
bool vis[N];

signed main()
{
	ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
	memset(dis,-1,sizeof dis);
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int l,k,d,c,a,b;
		cin>>l>>d>>k>>c>>a>>b;
		G[b].emplace_back(Edge(a,l,k,d,c));
	}
	dis[n]=(int)4e18;
	priority_queue<Node> q;
	q.push(Node(n,dis[n]));
	while(q.size())
	{
		auto [u,ds]=q.top();
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(auto&[j,l,k,d,c]:G[u])
		{
			// ds-c
			if(ds<c) continue;
			int gg=ds-c;
			// gg mod d=l mod d
			int p=l%d;
			int kk=gg%d;
			if(kk>=p) gg-=kk-p;
			else
			{
				gg-=kk;
				gg-=(d-p);
			}
			if(gg>=1)
			{
				int mm=(gg-l)/d;
				if(mm>k-1)
				{
					gg=(k-1)*d+l;
				}
				if(gg>=1)
				{
					if(dis[j]<gg)
					{
						dis[j]=gg;
						q.push(Node(j,dis[j]));
					}
				}
			}
		}
	}
	for(int i=1;i<n;i++) 
	{
		if(dis[i]==-1) cout<<"Unreachable\n";
		else cout<<dis[i]<<"\n";
	}
	return 0;
}
posted @ 2024-02-26 18:28  HappyBobb  阅读(1)  评论(0编辑  收藏  举报  来源