[NOIP simulation test]: number theory (mathematics)

Topic Portal (internal title 11)


Input Format

The first row, three integer $ T, K, M $, representing the number of data groups, integers and good standard range.
Then $ T $ lines, each integer $ n_i $, on behalf of a challenge.


Output Format

$ T $ output line, the first row for $ I $ I $ $ interrogation output an integer representing the number of $ Good $ n_i integer.
The answer must be no more than guarantee given $ M $.


Sample

Sample input 1:

1 0 23333
10

Sample output 1:

20

Sample input 2:

3 5 998244353
28
165
233

Sample Output 2:

42
9360
63360


Data range and tips

Sample 1 explanation:

Before $ 10 $ an excellent integer is $ 1,2,3,4,6,8,10,12,18,20 $.

data range:

For all data, $ 1 \ leqslant T \ leqslant 20,0 \ leqslant K \ leqslant 233,1 \ leqslant n_i \ leqslant M \ leqslant {10} ^ {18}.


answer

For $ p $ a prime number, we consider all the positive integers only comprises less than $ p $ prime factor set $ G $. Difficult to find:
  If $ x \ in G $, $ G $ and in the integer K has more than $ X $ $ $ small in number than the number of about $ X $, $ X $ i.e. definitely not good, the $ xp ^ c (c \ geqslant 0) $ will certainly not be good.
So that we can get a rough idea. We began to think that only $ 1 $ is good, the quality factor enumerate $ p $, for each of the original that is a good number $ x $, the $ xp ^ c (c \ geqslant 0) $ join the candidate list, then candidate list sorting, removing the already determined not to be a good number, enter the next iteration. Easy to show that, in this algorithm, not weed out a good number $ x $, is not going to make a good number were not originally in the follow-up process, become a good number, it is a good process to weed out the number of pruning is legal.
However, the scope of the enumeration of quality factor be? Lenovo $ K = 0 $ this classic problem, we know that for the first $ ^ {10} {18} $ range, taking $ 20 $ a qualitative factors are more than enough, because the added factor of greater mass is not optimal. In the $ K $ greater when we use "iteration to stability," the idea after each round of iteration to check whether the answers change if the answer is no change after a long period of iterations, we believe that the quality factor of $ p $ the upper bound has been reached. After practice, when $ K = 233 $, $ p $ maximum value is taken to $ 293 to $.
We consider how to remove determined not to be in a good number of iterations. Consider maintaining ago $ K + 1 $ large value, small to large to enumerate the candidate list of the number $ x $, if $ x $ smaller than $ K + 1 $ large value, we put this number removed. Otherwise, before updating the $ K + 1 $ large value. The above description can roughly estimate the complexity. When set $ K = 233 $, $ { 10} ^ {18} $ Good $ the number N is the number of $, through practice, it is known about $ $ $ N $ 50,000. Each extended up to a number of extensions to $ \ $ M number log, after pruning is complete, and return to the list size $ N $ or less.

Time complexity: $ \ Theta ((N \ times K \ times \ max (p) \ log M) $.

Expectations score: $ 100 $ points.

Actual score: $ 100 $ points.


代码时刻

#include<bits/stdc++.h>
using namespace std;
int T,K;
long long M;
int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293};
int cnt,num,size;
pair<int,long long> heap[200000],que[200000],flag[200000];
bool cmp(pair<int,long long> x,pair<int,long long> y){return x.second==y.second?x.first<y.first:x.second<y.second;}
void up(int x)
{
	while(x>1)
		if(heap[x]<heap[x>>1])
		{
			swap(heap[x],heap[x>>1]);
			x>>=1;
		}
		else break;
}
void insert(pair<int,long long> x){heap[++size]=x;up(size);}
void down(int x)
{
	int s=x<<1;
	while(s<=size)
	{
		if(s<size&&heap[s]>heap[s|1])s|=1;
		if(heap[s]<heap[x])
		{
			swap(heap[s],heap[x]);
			x=s;
			s=x<<1;
		}
		else break;
	}
}
void change(pair<int,long long> x){heap[1]=x;down(1);}
int main()
{
	scanf("%d%d%lld",&T,&K,&M);
	que[++cnt]=make_pair(1,1);
	for(int i=0;i<62;i++)
	{
		num=0;
		long long lft=0,rht=M/prime[i],k=0;
		while(lft<=rht)
		{
			lft=max(lft*prime[i],1LL);
			k++;
			for(int j=1;j<=cnt&&lft*que[j].second<=M;j++)
				flag[++num]=make_pair(que[j].first*k,lft*que[j].second);
		}
		sort(flag+1,flag+num+1,cmp);
		int lst=cnt;
		cnt=size=0;
		for(int j=1;j<=min(K+1,num);j++)
		{
			insert(flag[j]);
			que[++cnt]=flag[j];
		}
		for(int j=min(K+1,num)+1;j<=num;j++)
			if(flag[j].first>=heap[1].first)
			{
				change(flag[j]);
				que[++cnt]=flag[j];
			}
		if(lst==cnt)break;
	}
	while(T--)
	{
		int x;
		scanf("%d",&x);
		printf("%lld\n",que[x].second);
	}
	return 0;
}

rp++

Guess you like

Origin www.cnblogs.com/wzc521/p/11367276.html