【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;
}

  

posted @ 2016-07-23 19:48  Yangjiyuan  阅读(181)  评论(0编辑  收藏  举报