春测T2求调
  • 板块学术版
  • 楼主hahaxiang
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/3/5 16:48
  • 上次更新2023/10/23 22:57:12
查看原帖
春测T2求调
713562
hahaxiang楼主2023/3/5 16:48
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
int number[100000];
int len;
int n;
int ans;
int k;
int quickpower(int a,int b)
{
	int s=1,base=a;
	while(b!=0)
	{
		int last=s;
		if(b&1)
		{
			if(s>1e18/a)
			return LLONG_MAX;
			s*=base;
			if(s<last||s<last*a)
			return LLONG_MAX;
			if(s>1e18)
			return LLONG_MAX;
		}
		b>>=1;
		int Last=base;
		base*=base;
		if(base>1e18&&b!=0)
		return LLONG_MAX;
		if(base<Last&&b!=0||base<Last*a&&b!=0)
		return LLONG_MAX;//判超界
	}
	return s;
}
signed main()
{
	cin>>n>>k;
	if(k==1)
	{
		cout<<n;
		return 0;
	}
	for(int i=2;i<=sqrt(1e9);i++)
	{
		int c=i*i;
		while(c<=1e9)
		{
			number[++len]=c;
			c*=i;
		} 
	}
	sort(number+1,number+1+len);
	len=unique(number+1,number+1+len)-number-1;
	ans+=1;
	for(int i=k;i<=65;i++)
	{
		if(quickpower(2,i)>n)
		{
			break;
		}
		int l=2,r=1e9;
 		while(l<r)
		{
			int mid=(r+l)/2+1;
			if(quickpower(mid,i)<=n)
			{
				l=mid;
			}
			else
			{
				r=mid-1;
			}
		}//二分值
		int w=quickpower(l,i);
		int c=l;
		l=0,r=len;
		while(l<r)
		{
			int mid=(r+l)/2+1;
			if(quickpower(number[mid],i)<=w)
			{
				l=mid;
			}
			else
			{
				r=mid-1;
			}
		}//二分重复贡献
		ans+=c-1-l;//减掉1的贡献
	}
	cout<<ans;
	return 0;
}

wa最后三个点,都是多1,85pts 思路是对于每个x次方二分一个值 然后再二分小于这个值有重复贡献的(能表示为a^b(b>1)的)

2023/3/5 16:48
加载中...