11.4考试整理(11.5写)T1数论线性筛

【问题描述】
从1 − ?中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数
最大可能是多少。
【输入格式】
第一行一个数字?。
【输出格式】
一行一个整数代表答案对100000007取模之后的答案。
【样例输入】
7

【样例输出】
144

【数据规模与约定】
对于20%的数据,1 ≤ ? ≤ 100。
对于50%的数据,1 ≤ ? ≤ 5000。
对于70%的数据,1 ≤ ? ≤ 10^5。 
对于100%的数据,1 ≤ ? ≤ 5 × 10^6。

题解:这个题是个线性筛,当时不会也没看明白他让求什么。。考完试后听说这是个线性筛,然后用一个神奇的方法可以很快的求出你n个数种质数出现的次。偶数次直接加,奇数次减一再加。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;
const int p=100000007;
const int Max=5000005;
LL n,ans=1,cnt=0;
LL prime[Max],sh[Max];
LL num[Max];
LL ksm(LL x,LL y)
{
	if(y==0) return 1;
	if(y==1) return x;
	LL a=ksm(x,y/2);
	if(y%2==1) return a*a%p*x%p;
	else return a*a%p;
}

void find_prime()              //线性筛
{
	for(int i=2;i<=n;i++)
	{
		if(sh[i]==0) prime[++cnt] =i;
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
		{
			sh[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}

int main()
{
	freopen("hao.in","r",stdin);
	freopen("hao.out","w",stdout);
	scanf("%lld",&n);
	find_prime();
	for(LL i=1;i<=cnt;i++)//这就是神奇的方法
	{
		LL re=n;
		while (re!=0)
		{
			num[i]+=re/prime[i];
			re/=prime[i];
		}
	}
	for(int i=1;i<=cnt;i++)
	{
		ans*=ksm(prime[i],num[i]/2*2);	
		ans%=p;
	}
	printf("%lld",ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 

 

 

转载于:https://my.oschina.net/u/3009052/blog/782031

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值