Problem: ioi14_a
Categories: graph, math
Difficulty: medium
Time limit: 1000 ms | Memory limit: 256 MB

Taiwan has a big railway line connecting the western and eastern shores of the island. The line consists of blocks $m$. The consecutive blocks are numbered $0, \ldots, m - 1$, starting from the western end. Each block has a one-way west-bound track on the north, a one-way east-bound track on the south, and optionally a train station between them.

There are three types of blocks. A type $C$ block has a train station that you must enter from the northern track and exit to the southern track, a type $D$ block has a train station that you must enter from the southern track and exit to the northern track, and a type empty block has no train station. For example, in the following figure block 0 is type empty, block 1 is type $C$, and block 5 is type $D$. Blocks connect to each other horizontally. Tracks of adjacent blocks are joined by connectors, shown as shaded rectangles in the following figure.

![](https://ioi.contest.codeforces.com/espresso/365a386fce7b867cdf5592f3f5ed675f3cc2917d.png)

The railsystem has $n$ stations numbered from $0$ to $n - 1$. We assume that we can go from any station to any other station by following the track. For example we can go from station 0 to station 2 by starting from block 2, then passing through blocks 3 and 4 by the southern track, and then passing through station 1, then passing through block 4 by the northern track, and finally reaching station 2 at block 3.

Since there are multiple possible routes, the distance from one station to another is defined as the minimum number of connectors the route passes through. For example the shortest route from station 0 to 2 is through blocks $2-3-4-5-4-3$ and passes through 5 connectors, so the distance is $5$.

A computer system manages the railsystem. Unfortunately after a power outage the computer no longer knows where the stations are and what types of blocks they are in. The only clue the computer has is the block number of station 0, which is always in a type $C$ block. Fortunately the computer can query the distance from any station to any other station. For example, the computer can query "what is the distance from station $0$ to station $2$?" and it will receive $5$.

Task

You need to implement a function findLocation that determines for each station the block number and block type.

* void findLocation(int n, int first, int location[], int stype[])
  + $n$: the number of stations.
  + $first$: the block number of station $0$.
  + $location$: array of size $n$; you should place the block number of station $i$ into $location[i]$.
  + $stype$: array of size $n$; you should place the block type of station $i$ into $stype[i]$: $1$ for type $C$ and $2$ for type $D$.

You can call a function int getDistance(int i, int j) to help you find the locations and types of stations.

* getDistance(i, j) returns the distance from station $i$ to station $j$
* getDistance(i, i) will return $0$
* getDistance(i, j) will return $-1$ if $i$ or $j$ is outside the range $0 \le i, j \le n - 1$.

Input

The sample grader reads the input in the following format:

* line 1: the subtask number
* line 2: $n$
* lines $3 + i (0 \le i \le n - 1)$: $stype[i]$ ($1$ for type $C$ and $2$ for type $D$), $location[i]$.

Output

The sample grader will print Correct if $location[0] \ldots location[n - 1]$ and $stype[0] \ldots stype[n - 1]$ computed by your program match the input when findLocation returns, or Incorrect if they do not match.

Scoring

In allsubtasks the number of blocks $m$ is no more than $1\,000\,000$. In some subtasks the number of calls to getDistance is limited. The limit varies by subtask. Your program will receive 'wrong answer' if it exceeds this limit.

|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| Subtask | Points | $n$ | getDistance calls | note |
| 1 | 8 | $1 \le n \le 100$ | unlimited | Allstations except $0$ are in type $D$ blocks. |
| 2 | 22 | $1 \le n \le 100$ | unlimited | Allstations to the right of station $0$ are in type $D$ blocks, and allstations to the left of station $0$ are in type $C$ blocks. |
| 3 | 26 | $1 \le N \le 5\,000$ | $n(n - 1) / 2$ | No additional limits |
| 4 | 44 | $1 \le N \le 5\,000$ | $3(n - 1)$ | No additional limits |

Interactor / grader files:
grader.cpp: /* This is sample grader for the contestant */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "rail.h"

typedef struct Station {
  int index;
  int type;
  int location;
  int L,R;
}STATION;
long long cnt;
static int S,SUBTASK;
static STATION stations[10004];

int cmp_fun_1(const void *a,const void *b)
{
	STATION c,d;
	c = *(STATION*)(a);
	d = *(STATION*)(b);
  	return c.location < d.location ? -1 : 1;
}

int cmp_fun_2(const void *a,const void *b)
{
	STATION c,d;
	c = *(STATION*)(a);
	d = *(STATION*)(b);
  	return c.index < d.index ? -1 : 1;
}

void now_I_want_to_getLR(){
  int now = stations[S-1].index,i;
  for(i=S-2;i>=0;i--){
    stations[i].R = now;
    if(stations[i].type==2)	now = stations[i].index;
  }
  now = stations[0].index;
  for(i=1;i<S;i++){
    stations[i].L = now;
    if(stations[i].type==1)	now = stations[i].index;
  }
}

int getDistance(int x,int y)
{
  cnt++;
  if(x==y)	return 0;
  if(x<0 || x>=S || y<0 || y>=S)    return -1;
  if(stations[x].location > stations[y].location){
  	int tmp = x;
	x = y;
	y = tmp;
  }
  int ret = 0;
  if(stations[x].type==1 && stations[y].type==1){
    ret = stations[stations[y].R].location-stations[x].location+stations[stations[y].R].location-stations[y].location;
  }else if(stations[x].type==1 && stations[y].type==2){
    ret = stations[y].location-stations[x].location;
  }else if(stations[x].type==2 && stations[y].type==2){
    ret = stations[x].location-stations[stations[x].L].location+stations[y].location-stations[stations[x].L].location;
  }else if(stations[x].type==2 && stations[y].type==1){
    ret = stations[x].location-stations[stations[x].L].location+stations[stations[y].R].location
      -stations[stations[x].L].location+stations[stations[y].R].location-stations[y].location;
  }
  return ret;
}


void getInput()
{
  int g;
  g = scanf("%d",&SUBTASK);
  g = scanf("%d",&S);
  int s;
  for (s = 0; s < S; s++) {
    int type, location;
    g = scanf(" %d %d",&type,&location);
    stations[s].index = s;
    stations[s].location = location;
    stations[s].type = type;
    stations[s].L = -1;
    stations[s].R = -1;
  }
  qsort(stations, S, sizeof(STATION), cmp_fun_1);
  now_I_want_to_getLR();
  qsort(stations, S, sizeof(STATION), cmp_fun_2);
}

int serverGetStationNumber()
{
  return S;
}

int serverGetSubtaskNumber()
{
  return SUBTASK;
}

int serverGetFirstStationLocation()
{
  return stations[0].location;
}

int main()
{
  int i;
  getInput();
  cnt = 0;
  
  int location[10005];
  int type[10005];
  int ok = 1;
  findLocation(S, serverGetFirstStationLocation(),location, type);
  if(SUBTASK==3 && cnt>S*(S-1))	ok = 0;
  if(SUBTASK==4 && cnt>3*(S-1))	ok = 0;
  
  
  for (i = 0; i < S; i++)
    if(type[i]!=stations[i].type || location[i]!=stations[i].location)
      ok = 0;
  if(ok==0)	printf("Incorrect");
  else	printf("Correct");
  return 0;
}

rail.cpp: #include "rail.h"

void findLocation(int N, int first, int location[], int stype[])
{

}

rail.h: #ifndef __RAIL_H__
#define __RAIL_H__

#ifdef __cplusplus
extern "C" {
#endif
  void findLocation(int n, int first, int location[], int stype[]);
  
  int getDistance(int i, int j);
#ifdef __cplusplus
}
#endif

#endif /* __RAIL_H__ */