problem F:tanks A lotimagine you had a car with a very large gas tank-large enough to the whatever amount you need. You is traveling on a circular route on which there is a number of gas stations. the total gasinchallthe Stations isexactly the amount it takes to travel around the circuit once. When you arrive at a gasstation, you add all the that station's gas to your tank. Starting with an empty tank, it turns outthere isAt least one station to start, and a direction (clockwise or counter-clockwise)whereYou can make Itaround the circuit. (On the might ponder why This isThe Case-but trust us, it is.) Given the distance around the circuit, the locations of the gas stations, and the number of miles Yourcar could gousingjust the gas at each station, find all the stations and directions your can start at Andmake it around the circuit. Inputthere'll be a sequence of test cases. Each test Casebegins with a line containing-positive INTEGERSC and S, representing the total circumference,inchmiles, the of the circle and the total number of gas stations. Following Thisis s pairs of integers t and M. In each pair, T isAn integer between0and c−1measuringthe Clockwise location ( fromSome arbitraryfixedPoint on the circle) around the circumference of oneof, the gas stations and M isThe number of miles that can be drivenusingAll in the station . all of the locations is distinct and the maximum value of C is -, the. The last Test Case isFollowedby a pair of0' s.outputfor each test Case, Print the test CaseNumber (inchThe format showninchThe example below) followed by alist of pairs of valuesinchThe form I d,whereI isLocation and D iseither C, CC, or ccc,indicating that if starting with an empty tank, it ispossible to drive fromLocation I aroundinchaclockwise (C) direction, counterclockwise (CC) direction, or either direction (CCC), returning to Locationi. List the Stationsinchorder of increasing location. Sample InputTen 42 3 4 3 6 1 9 35 50 1 4 1 2 1 3 1 1 10 0Sample outputcase1:2C4Cc9Ccase2:0Ccc1Ccc2Ccc3Ccc4Ccc
Test instructions: give you a ring of length C, the ring above has m gas station, each gas station oil sum just enough for you to run a lap on the ring, at first your car is not oil, now you can choose a gas station as the starting point and get all the oil gas station, and then choose to walk clockwise or counterclockwise, Without a gas station you can get the oil there and ask if you can finally go back to the gas station where you chose to start. What is the M gas station can be used as a starting point, if you should start clockwise or counterclockwise or two directions can be?
Idea: For the ring can be turned into a straight line, the gas station in order. The amount of oil required to use the oil from the petrol filling station need_i to the I+1 petrol filling station, such as 1 (2)---5 (3)---7 (1), then 1 to the petrol station 5, i.e. need 2, from the petrol station 2 to the petrol station 5 7, or need 2
Then for the I gas station can as a starting point, the equivalent of starting from I need array prefix and cannot be negative. Then we can directly do the prefix and then for an interval [l,r], to the L position as the starting point of the prefix and no negative in this interval, equivalent to Sum[l-1]<=min (Sum[k]) L<=k<=r equivalent to the value of this interval minus sum[ L-1] Query interval minimum value can be handled with RMQ
For the counter-clockwise approach is exactly the same, reverse the need array.
#include <cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<string>#include<stack>#include<cmath>#include<cstdlib>#include<iostream>#include<map>#include<Set>using namespacestd;Const intINF =0x3f3f3f3f; typedefLong Longll;Const intN = 5e5 + -;intSum1[n], sum2[n];intDir[n];intdp[n][ -];intMm[n];intN, K;structNode {intT, M; FriendBOOL operator<(Node A, Node B) {returnA.T <b.t; };}; Node G[n];voidINITRMQ (intNnintb[]) {mm[0] = -1; for(inti =1; I <= nn; ++i) {Mm[i]= ((I & (i-1)) ==0) ? Mm[i-1] +1: Mm[i-1]; dp[i][0] =B[i]; } for(intj =1; J <= Mm[nn]; ++j) for(inti =1; i + (1<< j)-1<= nn; ++i) dp[i][j]= Min (Dp[i][j-1], Dp[i + (1<< (J-1))][j-1]);}intRmqintXinty) {intK = Mm[y-x +1]; returnMin (Dp[x][k], Dp[y-(1<< k) +1][k]);}voidinit1 () {intT = k *2; memset (dir,0,sizeofdir); sum1[1] =0; for(inti =2; I <= T; ++i) {ints = (G[i].t-g[i-1].t + N)%N; Sum1[i-1] = Sum1[i-2] + g[i-1].M-s; } initrmq (T, sum1);}voidInit2 () {intT = k *2; sum2[1] = sum2[t +1] =0; for(inti = T; i >1; --i) {ints = (G[i].t-g[i-1].t + N)%N; Sum2[i]= Sum2[i +1] + G[I].M-s; } initrmq (T, sum2);}voidsolve1 () { for(inti =1; I <= K; ++i) {if(Sum1[i-1] <= RMQ (i, i + K-1) ) {dir[g[i].t]=1; } }}voidsolve2 () {intT = k *2; for(inti = T; i > t-k; --i) {if(Sum2[i +1] <= RMQ (i-k +1, i)) { if(dir[g[i].t]) dir[g[i].t] =3; Elsedir[g[i].t] =2; } }}intMain () {#ifdef LOCAL freopen ("In.txt","R", stdin);#endif intCAS =1; while(~SCANF ("%d%d", &n, &k)) {if(n = =0&& k = =0) Break; for(inti =1; I <= K; ++i) {scanf ("%d%d", &G[I].T, &g[i].m); } Sort (g+1, G +1+k); for(inti =1; I <= K; ++i) {g[i+ k].t =g[i].t; G[i+ K].M =g[i].m; } //for (int i = 1; I <= k * 2; ++i) printf ("%d%d\n", g[i].t, G[I].M);init1 (); Solve1 (); Init2 (); Solve2 (); printf ("Case %d:", cas++); for(inti =1; I <= K; ++i) {if(dir[g[i].t] = =1) printf ("%d C", g[i].t); if(dir[g[i].t] = =2) printf ("%d CC", g[i].t); if(dir[g[i].t] = =3) printf ("%d CCC", g[i].t); } puts (""); } return 0;}
Gym 100646 F Tanks a lot RMQ