【bzoj4320】ShangHai2006 Homework
若Y小于等于sqrt(300000),暴力,对所有的插入的数都更新mn[i]。
若Y大于sqrt(300000),枚举kY,用并查集维护>=i的第一个数,这样只支持删除操作是O(1),然后倒着枚举一边,删除一个数x那么就fa[x]=fa[x+1]
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define MAXN 300010 #define N 300000 struct Node { int t,k,ans; }q[MAXN]; int n; int fa[MAXN],f[MAXN],m[310]; char ch[10]; int find(int x) { return fa[x]==x ? fa[x] : fa[x]=find(fa[x]); } int main() { memset(m,127/3,sizeof(m)); scanf("%d",&n); for (int i=1;i<=N+1;i++) fa[i]=i; for (int i=1;i<=n;i++) { scanf("%s%d",ch,&q[i].k); q[i].t=ch[0]-'A'; if (q[i].t==0) { for (int j=1;j<=300;j++) m[j]=min(m[j],q[i].k%j); f[q[i].k]=1; } if (q[i].t==1 && q[i].k<=300) q[i].ans=m[q[i].k]; } for (int i=1;i<=N;i++) if (!f[i]) fa[i]=i+1; for (int i=n;i>=1;i--) { if (q[i].t==0) fa[q[i].k]=q[i].k+1; else { int t,minn=N; if (q[i].k>300) { for (int j=0;j<=N;j+=q[i].k) { t=find(max(j,1)); if (t<=N) minn=min(minn,t%q[i].k); } q[i].ans=minn; } } } for (int i=1;i<=n;i++) if (q[i].t) printf("%d\n",q[i].ans); return 0; }