题意:
对一个集合,有两种操作,
一:将某个元素加入集合中二:个是问当前集合中mod y 最小的数,如果有多个,输出最近加入的那个元素的输入时间,在本题指的是该元素加入集合时操作一的次数
当y比较大
每次对[0,y-1]、[y,2y-1]...每个长度为y的区间查询最小的存在的数。。。最后比较得到答案
y比较小的话,如果这样遍历 区间最多会有 500000/y个。。所以不如直接遍历出现过的所有数。最多只有4W个。。。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const int inf=2147483647;
const double pi=acos(-1.0);
double eps=0.000001;
struct tree
{
int st_min[500005*4];
inline int minn(int a,int b) { return a>b?b:a; }
inline int maxx(int a,int b) { return a>b?a:b; }
void pushup(int rt)
{
st_min[rt]=minn(st_min[rt<<1],st_min[rt<<1|1]);
}
void update(int l,int r,int rt,int num,int val)
{
if (l==r&&r==num)
{st_min[rt]=val;return;}
int m=(l+r)>>1;
if (num<=m)
update(l,m,rt<<1,num,val);
else
update(m+1,r,rt<<1|1,num,val);
pushup(rt);
}
int query(int ql,int qr,int l,int r,int rt)
{
if (ql>r||qr<l) return inf;
if (ql<=l&&qr>=r)
return st_min[rt];
int m=(l+r)>>1;
int ret1=query(ql,qr,l,m,rt<<1);
int ret2=query(ql,qr,m+1,r,rt<<1|1);
return minn(ret1,ret2);
}
void build(int l,int r,int rt)
{
st_min[rt]=inf;
if (l==r) return ;
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
}
};
tree tp;
int tm[500005];
int vis[500005];
void solve(int y,int cun)
{
int i;
if (y<=5000)
{
int ans=inf;
int ans_id;
for (i=cun;i>=1;i--)
{
if (vis[i]%y<ans)
{
ans=vis[i]%y;
ans_id=i;
}
if (ans==0) break;
}
if (ans==inf) printf("-1\n");
else
printf("%d\n",ans_id);
return ;
}
else
{
int ans=inf;
int ans_id;
for (i=0;i<=500000+y;i+=y)
{
int high=i+y-1;
// if (high>500000) high=500000;
int xx=tp.query(i,high,1,500000,1);
if (xx==inf) continue;
if (xx%y<=ans)
{
if (ans==xx%y)
{
if (tm[xx]>ans_id)
ans_id=tm[xx] ;
}
else
ans_id=tm[xx];
ans=xx%y;
}
}
if (ans==inf) printf("-1\n");
else
printf("%d\n",ans_id);
}
}
int main()
{
int t;
int cnt=1;
while(cin>>t)
{
if (!t) break;
memset(tp.st_min,0,sizeof(tp.st_min));
memset(tm,0,sizeof(tm));
if (cnt!=1) printf("\n");
printf("Case %d:\n",cnt++);
getchar();
int i;
tp.build(1,500000,1);
int cun=0;
int yy;
char ty[15];
for (i=1;i<=t;i++)
{
scanf("%s%d", ty,&yy);
if (ty[0]=='B')
{
cun++;
tm[yy]=cun;
tp.update(1,500000,1,yy,yy);
vis[cun]=yy;
}
else
{
solve(yy,cun);
}
}
}
return 0;
}