Description
We believe that every inhabitant of this universe eventually will find a way to live together in harmony and peace; that trust, patience, kindness and loyalty will exist between every living being of this earth; people will find a way to appreciate and cooperate with each other instead of continuous bickering, arguing and fighting. Harmony — the stage of society so many people dream of and yet it seems so far away from now…
Fortunately, the method of unlocking the key to true Harmony is just discovered by a group of philosophers. It is recorded on a strange meteorite which has just hit the earth. You need to decipher the true meaning behind those seemingly random symbols… More precisely, you are to write a program which will support the following two kinds of operation on an initially empty set S:
- B X: Add number X to set S. The Kth command in the form of B X always happens at time K, and number X does not belong to set S before this operation.
- A Y : Of all the numbers in set S currently, find the one which has the minimum remainder when divided by Y. In case a tie occurs, you should choose the one which appeared latest in the input. Report the time when this element is inserted.
It is said that if the answer can be given in the minimum possible time, true Harmony can be achieved by human races. You task is to write a program to help us.
Input
There are multiple test cases in the input file. Each test case starts with one integer T where 1 ≤ T ≤ 40000. The following T lines each describe an operation, either in the form of “B X” or “A Y ” where 1 ≤ X ≤ 500 000, 1 ≤ Y ≤ 1 000 000.
T = 0 indicates the end of input file and should not be processed by your program.
Output
Print the result of each test case in the format as indicated in the sample output. For every line in the form of “A Y”, you should output one number, the requested number, on a new line; output -1
if no such number can be found. Separate the results of two successive inputs with one single blank line.
Sample Input
5 B 1 A 5 B 10 A 5 A 40 2 B 1 A 2 0
Sample Output
Case 1: 1 2 1 Case 2: 1
Source
题解:我们可以开一个x[i]大小的数组q,每一次插入的时候,更新这个数组中的每一个值,询问的时候就直接输出q[x[i]]即可。但这道题中x[i]的大小为50000,O(N²)的算法承受不了,那怎么办呢?用分段的思想解决,开一个长度为MAX(x[i])的数组c,每插入一个数,就在数组c中标记已插入,询问操作的时候分别查找1~x[i]-1,x[i]~2*x[i]-1,2*x[i]~3*x[i]-1, ……,k*x[i]~max(x[i]),这些段中取模值最小的数,时时更新答案。在查找段最小值的时候,可以利用树状数组或者线段树两种数据结构,把时间复杂度降到O(logMAX(x[i]))。但是,在x[i]很小的时候,时间复杂度就降到了O(N)(还有常数时间。。。)。所以只用线段树也是过不了的。那么就综合两种算法的优点,每次询问的时候,如果x[i]小于lim,则到q数组中直接输出答案,大于lim的询问进行分段查找,每次插入两个数组q和c即可。然后调整一下lim的值,就可以有很好的时效表现了。
AC CODE
//我用的是树状数组的做法,常数小。(虽然依然很慢。。。)
program pku_3145;
const lim=1000;
var q,c,a,t:array[1..max] of longint;
//============================================================================
procedure ins(x:longint);
var j:longint;
begin
end;
//============================================================================
function ask(x:longint):longint;
begin ask:=0;
end;
//============================================================================
function askmin(be,en:longint):longint;
var l,r,mid,pre,now:longint;
begin
end;
//============================================================================
procedure enquiry(x:longint);
var ans,l,r,k:longint;
begin
end;
//============================================================================
begin
end.