若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;
}
【bzoj4320】ShangHai2006 Homework
原文:http://www.cnblogs.com/yangjiyuan/p/5699400.html