HDU 5812 Distance 暴力+素数打表

/*
   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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值