您的位置:首页 > 大数据 > 人工智能

4320: ShangHai2006 Homework 并查集+离线处理 思路题

2016-02-03 09:43 411 查看
好题。。我不会做。。

在我冥思苦想无果的时候发现。。发现。。yzy大神已经A掉了qwq。

果然我这种蒟蒻就该早退役。顺便膜Au爷。

本题分为两种情况讨论。

令M=sqrt(300000).

当Y < M,对所有的插入的数都更新mn[i],暴力就好。。

否则枚举Y的倍数,找第一个比Y的倍数大的数,这个可以用并查集来维护。

因为维护的时候是删除数,所以要离线倒着做。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[300005],num[100005];
int mn[605],ans[100005];
int n;
char opt[100005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
int find(int i)
{
return f[i]==i?i:f[i]=find(f[i]);
}
int main()
{
n=read();
for (int i=1;i<=300000;i++) f[i]=i+1;
memset(mn,127,sizeof(mn));
for (int i=1;i<=n;i++)
{
char s[5];
scanf("%s",s);
opt[i]=s[0];
num[i]=read();
if (opt[i]=='A')
{
for (int j=1;j<=540;j++) mn[j]=min(mn[j],num[i]%j);
f[num[i]]=num[i];
}
else if (num[i]<=540) ans[i]=mn[num[i]];
}
for (int i=n;i;i--)
{
if (opt[i]=='A') f[num[i]]=f[num[i]+1];
else if (num[i]>540)
{
ans[i]=find(1)%num[i];
for (int j=num[i];j<=300000;j+=num[i])
{
int x=find(j);
if (x) ans[i]=min(ans[i],x%num[i]);
}
}
}
for (int i=1;i<=n;i++)
if (opt[i]=='B') printf("%d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: