题目链接:http://poj.org/problem?id=3145

/**//*
题意:
对于一个集合S,一共两种操作:
1. B X: 添加一个数X到S. 第K个B操作发生在第K个时间点,并且每个之前S集合中没有X。
2. A Y: 在S集合中所有数中, 被Y除后余数最小的,如果有相同的,选择最近插入的那个
数,如果没有则输出-1

题解:
树状数组 或者 线段树

思路:
这题主要看怎么去平衡了。如果数据量很小,可以直接开一个一维数组,下标表示除
数Y,每次B操作的时候遍历一遍该数组,将答案存下来。但是当插入操作很多的时候这个
复杂度就比较大了,因为数字的范围是(1 <= X, Y <= 500000),每次都执行插入操作,并
且遍历整个数组进行更新的话总的执行次数就是500000^2,于是可以换个角度,想想其他
办法,用每个数的值作为树状数组的下标,每次B操作就将该数插入到树状数组中,等到A
操作进行询问时,利用树状数组的成段求和,统计[0, Y-1]、[Y, 2*Y-1]
这些区间段
中最小的sum不为0的数,然后取一个最小值。这样的方法当Y很大的时候复杂度是很小的,
但是如果Y是1的话就退化成O(n)了。于是我们可以将以上两种方法结合一下,Y的值比较小
的时候存在数组中,即使读取,大的时候利用树状数组+二分进行统计找出最小值。
这个平衡的系数可以取sqrt(50000),但是关键还是要看题目的数据,所以如果超时就
左右稍作调整即可。
*/
#include <iostream>

using namespace std;

#define mod_split 6208
#define maxn 500010
int n;
int ans[mod_split + 1], tim[ mod_split + 1 ];
int c[maxn];
int nt[maxn];


inline int lowbit(int x)
{
return x & (-x);
}


void add(int pos)
{

while(pos < maxn)
{
++c[pos];
pos += lowbit(pos);
}
return ;
}


int sum(int pos)
{
int s = 0;

while(pos > 0)
{
s += c[pos];
pos -= lowbit(pos);
}
return s;
}


int Bin(int l, int r)
{
if(!l) l++;
if(l >= maxn) l = maxn - 1;
if(r >= maxn) r = maxn - 1;

int ans = -1;
int pre = sum(l - 1);

while(l <= r)
{
int m = (l + r) >> 1;

if(sum(m) - pre > 0)
{
r = m - 1;
ans = m;
}else
l = m + 1;
}
return ans;
}


int main()
{
int i, j;
int Case = 1;

while(scanf("%d", &n) != EOF && n)
{
if(Case != 1)
puts("");


for(j = 0; j <= mod_split; j++)
{
ans[j] = mod_split + 1;
tim[j] = -1;
}
memset(c, 0, sizeof(c));
printf("Case %d:\n", Case ++ );
int Time = 0;

for(i = 1; i <= n; i++)
{
char str[10];
int x;
scanf("%s %d", str, &x);

if(str[0] == 'B')
{
Time ++;

for(j = 1; j <= mod_split; j++)
{
int p = x % j;

if(p <= ans[j])
{
ans[j] = p;
tim[j] = Time;
}
}
add(x);
nt[x] = Time;

}else
{

if(x <= mod_split)
{
printf("%d\n", tim[x]);

}else
{
int l = 0, r = x - 1;
int MinVal = -1;
int MinTime;

while(1)
{
int v = Bin(l, r);

if(v != -1)
{
int Mod = v % x;

if(Mod < MinVal || MinVal == -1)
{
MinVal = Mod;
MinTime = nt[v];

}else if(Mod == MinVal)
{
if(MinTime < nt[v])
MinTime = nt[v];
}
}
if(l >= maxn || r >= maxn)
break;
l += x;
r += x;
}

if(MinVal != -1)
printf("%d\n", MinTime);
else
printf("-1\n");
}
}
}

}
return 0;
}