题意:
对一个集合,有两种操作,
一:将某个元素加入集合中二:个是问当前集合中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; }