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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "krazki.h"
#include "message.h"
#include<bits/stdc++.h>

#include<cstdio>
using namespace std;

#define R(p, k) for(int i = p; i <= k; i++)
#define RI(i, p, k) for(int i = p; i <= k; i++)
#define IR(k, p) for(int i = k; i >= p; i--)
#define IRI(i, p, k) for(int i = k; i >= p; i--)
#define DEB 0
	
#if DEB
	#define EPRLL(a) fprintf(stderr, "%s %lld ", #a, a);
	#define EPR(a) fprintf(stderr, "%s %d ", #a, a);
	#define EPRS(a) fprintf(stderr, "%s\n", a);
	#define EPRN fprintf(stderr, "\n");
#else
	#define EPRLL(a)
  #define EPR(a)
	#define EPRS(a)
  #define EPRN 
#endif

const int MN=2e7+5;
long long toy[MN];
int b, f, d, pos, nr=0;

/*long long toy(int i){
  memtoy[i-b];
}
void ptoy(int i, long long*/

int main() {
  d=(PipeHeight()+NumberOfNodes()-1)/NumberOfNodes();
  b=1+MyNodeId()*d;
  f=min(PipeHeight(), b+d-1);
  pos=f+1;
  if(MyNodeId()==nr){
    EPR(MyNodeId());
    EPR(b);
    EPR(f);
    EPRN;
  }
  
  //making toy not broadening

  long long locmini=(long long)1e18+5, mini=(long long)1e18+5;
  R(b, f){
    toy[i-b]=HoleDiameter(i);
    locmini=min(locmini, toy[i-b]);
  }
  if(MyNodeId()!=0){
    Receive(MyNodeId()-1);
    mini=GetLL(MyNodeId()-1);
    locmini=min(locmini, mini);
  }
  
  if(MyNodeId()!=NumberOfNodes()-1){
    PutLL(MyNodeId()+1, locmini);
    Send(MyNodeId()+1);
  }
  
  
  R(b, f){
    toy[i-b]=min(toy[i-b], mini);
    mini=toy[i-b];
    if(MyNodeId()==nr){
      EPR(i);
      EPRLL(toy[i-b]);
    }
  }
  
  //Puting discs
  
  RI(j, 1, NumberOfDiscs()){
    long long disc;
    //take disc
    if(MyNodeId()==NumberOfNodes()-1){
      disc=DiscDiameter(j);
    }
    else{
      Receive(MyNodeId()+1);
      disc=GetLL(MyNodeId()+1);
    }
    if(MyNodeId()==nr){
      EPRLL(disc);
    }
    
    //quick check
    if(disc==-1){
      if(MyNodeId() > 0){
        PutLL(MyNodeId()-1, -1);
        Send(MyNodeId()-1);
      }  
      continue;
    }
    if(pos<=b || disc>toy[0]){
      pos=b-1;
      if(MyNodeId() > 0){
        PutLL(MyNodeId()-1, disc);
        Send(MyNodeId()-1);
      } 
      continue;
    }
    
    //go with disc up
    pos--;
    IR(pos, b){
      if(toy[pos-b]>=disc){
        break;
      }
      pos--;
    }
    
    if(MyNodeId()==nr){
      EPR(pos);
    }
    
    //tell to previous node
    if(MyNodeId() > 0){
      if(pos<b){
        PutLL(MyNodeId()-1, disc);
        Send(MyNodeId()-1);
        continue;
      } 
      else{
        PutLL(MyNodeId()-1, -1);
        Send(MyNodeId()-1);
        continue;
      } 
    
    }
    
  }
  if(pos<=f){
    if(pos>=b){
      printf("%d\n", pos);
    }
    else{
      if(MyNodeId()==0)
        printf("-1\n");
    }
  }
  
  return EXIT_SUCCESS;
}