1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "queue"
using namespace std; #define MAXN 200006
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) typedef long long ll; int n , m; int sz;
struct fk { int t , T , l , r , c; } A[MAXN] ;
multiset<pii> S[MAXN << 2][2];
void ins( int rt , int l , int r , int idx ) { S[rt][0].insert( mp( A[idx].l + A[idx].T - 1 , idx ) ); S[rt][1].insert( mp( A[idx].l - A[idx].T - 1 , idx ) ); if( l == r ) return; int m = l + r >> 1; if( A[idx].t <= m ) ins( rt << 1 , l , m , idx ); else ins( rt << 1 | 1 , m + 1 , r , idx ); }
priority_queue<pair<ll,int>> Q; ll dis[MAXN]; int vis[MAXN];
ll ds;
void era( int rt , int w , pair<int,int> p ) { while( rt ) { S[rt][w].erase( S[rt][w].find( p ) ); rt >>= 1; } } int w , lim , L , R; void fuck( int rt , int l , int r ) { if( S[rt][w].empty() ) return; int i = S[rt][w].begin() -> se; if( lim < ( w ? A[i].l - A[i].T - 1 : A[i].l + A[i].T - 1 ) ) return; if( l == r ) { while( lim >= ( w ? A[i].l - A[i].T - 1 : A[i].l + A[i].T - 1 ) ) { if( !vis[i] && dis[i] > ds ) { dis[i] = ds; vis[i] = 1; Q.push( mp( -( ds + A[i].c ) , i ) ); } era( rt , w , *S[rt][w].begin() ); if( S[rt][w].empty() ) return; i = S[rt][w].begin() -> se; } return; } int m = l + r >> 1; if( L <= m ) fuck( rt << 1 , l , m ); if( R > m ) fuck( rt << 1 | 1 , m + 1 , r ); }
void solve() { cin >> n >> m; vi ts; rep( i , 1 , m ) { int t , l , r , c; scanf("%d%d%d%d",&t,&l,&r,&c); A[i] = (fk) { 0 , t , l , r , c }; ts.pb( t ); } sort( all( ts ) ); ts.erase( unique( all( ts ) ) , ts.end() ); rep( i , 1 , m ) A[i].t = lower_bound( all( ts ) , A[i].T ) - ts.begin() + 1; sz = ts.size(); rep( i , 1 , m ) if( A[i].l != 1 ) ins( 1 , 1 , sz , i );
memset( dis , 0x3f , sizeof dis ); rep( i , 1 , m ) if( A[i].l == 1 ) dis[i] = 0 , Q.push( mp( -A[i].c , i ) ); while( !Q.empty() ) { auto t = Q.top().se; ds = -Q.top().fi; Q.pop(); w = 0 , lim = A[t].r + A[t].T , L = A[t].t , R = sz; fuck( 1 , 1 , sz ); w = 1 , lim = A[t].r - A[t].T , L = 1 , R = A[t].t - 1 ; if( A[t].t ) fuck( 1 , 1 , sz ); } ll as = 0x3f3f3f3f3f3f3f3f; rep( i , 1 , m ) if( A[i].r == n ) as = min( as , dis[i] + A[i].c ); cout << ( as > 1e18 ? -1 : as ) << endl; }
signed main() {
solve(); }
|