您的位置:首页 > 其它

HDU 5812 Distance 暴力+素数打表

2017-07-16 21:21 369 查看
/*
I insert x;
D delect x;
Q query min(d(x,y);
d(x,y) =x 乘或除一个素数 变成y的最小次数;

d(x,y) =ans[x/gcd(x,y)]+ans[y/gcd(x,y]; ans[i] i的素因子数;
保留之前插入 y时,每一个y因子对应的ans[y/i]值 ->因子,ans值较小,
作为查询表的key 统计满足条件的y个数 ->C[i][ans[y/i]
查询暴力每个因子,如果有gcd时,显然最小。
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<set>
using namespace std;
const int Max=1000000+1;
int ans[Max]={0};
int C[Max][21];
void init()
{
for(int i=2;i<=1000000;i++)
{
if(!ans[i])
{
ans[i]=1;
for(int j=i+i;j<=1000000;j +=i) ans[j]=ans[j/i]+1;
}
}
}
int main()
{
int n,x,cas=0;
init();
char q[2];
set<int> s;
while(scanf("%d",&n)&&n)
{
printf("Case #%d:\n",++cas);
s.clear();
memset(C,0,sizeof(C));
for(int i=1;i<=n;i++)
{
scanf("%s%d",q,&x);
if(q[0]=='I')
{
if(s.count(x)) continue;
else
{
s.insert(x);
for(int i=1;i<=sqrt(x)+1;i++)
{
if(x%i==0)
{
C[i][ans[x/i]]++;
C[x/i][ans[i]]++;
}
}
}
}
if(q[0]=='D')
{
if(!s.count(x)) continue;
else
{
s.erase(x);
for(int i=1;i<=sqrt(x)+1;i++)
{
if(x%i==0)
{
C[i][ans[x/i]]--;
C[x/i][ans[i]]--;
}
}
}
}
if(q[0]=='Q')
{
int Min=1234;
if(s.size()==0)
{
printf("-1\n");
continue;
}
for(int i=1;i<=sqrt(x)+1;i++)
{
if(x%i==0)
{
int j;
for(j=0;j<=20;j++)
if(C[i][j])
{
Min=min(Min,ans[x/i]+j);
break;
}

for(j=0;j<=20;j++)
if(C[x/i][j])
{
Min=min(Min,ans[i]+j);
break;
}
}
}
printf("%d\n",Min);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: