import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.*;
public class Main
{
public interface SegmentedArray<Comparable>
{
void set
(int fromIndex,
int toIndex,
Comparable value
);
}
public class SegmentedArrayImpl<Item extends Comparable<Item>> implements SegmentedArray<Item>
{
private int size;
private int segmentSize;
public SegmentedArrayImpl(int aSegmentSize, int aSegmentCount)
{
segmentSize = aSegmentSize;
size = segmentSize * aSegmentCount;
segments
= new Object[aSegmentCount
][segmentSize
]; }
public int indexOf(Item value, int fromIndex)
{
if (fromIndex >= size)
{
return -1;
}
int segmentIndex = findSegmentIndex(fromIndex);
int indexInSegment = fromIndex - segmentIndex * segmentSize;
while (segmentIndex < segments.length)
{
// @SuppressWarnings("unchecked")
if (((Item) (segments[segmentIndex][indexInSegment])).compareTo(value) == 0)
{
return segmentIndex * indexInSegment;
}
indexInSegment++;
if (indexInSegment == segmentSize)
{
indexInSegment = 0;
segmentIndex++;
}
}
return -1;
}
public void set(int fromIndex, int toIndex, Item value)
{
if (fromIndex >= size || toIndex >= size || fromIndex > toIndex)
{
return;
}
int index = fromIndex;
int segmentIndex = findSegmentIndex(fromIndex);
int indexInSegment = fromIndex - segmentIndex * segmentSize;
while (segmentIndex < segments.length && index <= toIndex)
{
// @SuppressWarnings("unchecked")
segments[segmentIndex][indexInSegment] = value;
index++;
indexInSegment++;
if (indexInSegment == segmentSize)
{
indexInSegment = 0;
segmentIndex++;
}
}
}
public Item min(int fromIndex, int toIndex)
{
if (fromIndex >= size || toIndex >= size || fromIndex > toIndex)
{
return null;
}
int index = fromIndex;
int segmentIndex = findSegmentIndex(fromIndex);
int indexInSegment = fromIndex - segmentIndex * segmentSize;
Item minimum = null;
while (segmentIndex < segments.length && index < toIndex)
{
// @SuppressWarnings("unchecked")
Item val = (Item) segments[segmentIndex][indexInSegment];
if (minimum == null || val.compareTo(minimum) < 0)
{
minimum = val;
}
index++;
indexInSegment++;
if (indexInSegment == segmentSize)
{
indexInSegment = 0;
segmentIndex++;
}
}
return null;
}
// check if the absolute index falls into given segment index
private int compareIndexToSegment(int index, int segmentIndex)
{
int lowerIndex = segmentIndex * segmentSize;
int higherIndex = (segmentIndex + 1) * segmentSize - 1;
if (index < lowerIndex) // index falls before segment
{
return -1;
}
else if (index > higherIndex) // index falls after segment
{
return 1;
}
return 0;
}
// find segment that contains given absolute index using binary search
// in array
private int findSegmentIndex(int index)
{
int lo = 0; // lower segment index
int hi = segments.length - 1; // higher segment index
while (lo <= hi)
{
int mid = lo + (hi - lo) / 2; // middle segment index
int cmp = compareIndexToSegment(index, mid);
if (cmp < 0)
{
hi = mid - 1;
}
else if (cmp > 0)
{
lo = mid + 1;
}
else if (cmp == 0)
{
return mid;
}
}
return lo;
}
public void show()
{
for (int i = 0; i < segments.length; i++)
{
System.
out.
printf("segment#%d { ", i
);
for (int j = 0; j < segmentSize; j++)
{
System.
out.
print((Item
) segments
[i
][j
]); }
}
}
}
public static Vector
<String
> parseTextToTokens
(String text
) {
Vector<String> tokens = new Vector<String>();
while (st.hasMoreTokens())
{
tokens.add(st.nextToken());
}
return tokens;
}
{
try
{
}
{
}
return x;
}
public static void main
(String[] args
) {
Main obj = new Main();
SegmentedArrayImpl<String> storage = obj.new SegmentedArrayImpl<String>(4, 4);
Scanner in
= new Scanner
(System.
in);
for (;;)
{
String inputLine
= in.
nextLine();
if (inputLine.isEmpty())
{
continue;
}
Vector<String> inputTokens = parseTextToTokens(inputLine);
if (inputTokens.size() > 0)
{
cmd = inputTokens.get(0);
}
if (inputTokens.size() > 1)
{
arg1 = inputTokens.get(1);
}
if (inputTokens.size() > 2)
{
arg2 = inputTokens.get(2);
}
if (inputTokens.size() > 3)
{
arg3 = inputTokens.get(3);
}
if (cmd.equals("exit"))
{
break;
}
else if (cmd.equals("show"))
{
storage.show();
}
else if (cmd.equals("index"))
{
String value
= (arg1
!= null && !arg1.
isEmpty()) ? arg1
: null; Integer fromIndex
= (arg2
!= null) ? strToInt
(arg2
) : null;
if (value == null || fromIndex == null)
{
System.
out.
printf("*** ERROR: wrong arguments: <%s> <%s> <%d>\n", cmd, arg1, arg2
); continue;
}
System.
out.
println(storage.
indexOf(value, fromIndex
)); }
else if (cmd.equals("set"))
{
Integer fromIndex
= (arg1
!= null) ? strToInt
(arg1
) : null; Integer toIndex
= (arg2
!= null) ? strToInt
(arg2
) : null; String value
= (arg3
!= null && !arg3.
isEmpty()) ? arg3
: null;
if (fromIndex == null || toIndex == null || value == null)
{
System.
out.
printf("*** ERROR: wrong arguments: <%s> <%d> <%d> <%s>\n", cmd, arg1, arg2, arg3
); continue;
}
storage.set(fromIndex, toIndex, value);
}
else if (cmd.equals("min"))
{
Integer fromIndex
= (arg1
!= null) ? strToInt
(arg1
) : null; Integer toIndex
= (arg2
!= null) ? strToInt
(arg2
) : null;
if (fromIndex == null || toIndex == null)
{
System.
out.
printf("*** ERROR: wrong arguments: <%s> <%d> <%d>\n", cmd, arg1, arg2
); continue;
}
System.
out.
println(storage.
min(fromIndex, toIndex
)); }
}
in.close();
}
}