2023.10.4测试

T1 最短路

T2 欧拉函数

给定常数 BT 组测试数据,每次给定 l,r,求

x=lrφ(maxi=1xφ(x)B)(x)

maxi=1xφ(x)B0φ(maxi=1xφ(x)B)(x)=x

1T1051r,B109

暴力做 r106 拿到 72

其实很容易想到 φ 迭代 log 次后就会变成 1,但是一些具体的实现没有想到

对于 iB 的贡献就是 i,对于第一个 φ(x)>logV+1x[x,r] 的贡献都是 1

问题是怎么找到这个 x

打表发现质数的密度并不小,而质数的 φ 值就是自己减 1,所以 maxi=1xφ(x) 就约等于 i 前面的第一个质数的 φ 值。因此可以设一个阈值 M,令 x=B+M+1,这样对于 [x,n] 的贡献都直接计算

对于 [B,B+M] 的部分,暴力计算即可

#include<bits/stdc++.h>
#pragma GCC optimize(3,"Ofast","inline")
#define LL long long 
using namespace std;

const int N=1e6+10,M=200;

int T,l,r,B;
LL g[M+10];

int getphi(int x)
{
	int res=x;
	for(int i=2; i*i<=x; i++)
	{
		if(x%i==0)
		{
			res=1LL*res*(i-1)/i;
			while(x%i==0)
				x/=i;
		}
	}
	if(x>1)
		res=1LL*res*(x-1)/x;
	return res;
}

LL f(int k,int x)
{
	if(k<=0)
		return x;
	if(k==1)
		return (LL)getphi(x);
	if(x==1)
		return 1;
	return f(k-1,getphi(x));
}

bool isprime(int x)
{
	if(x==1)
		return 0;
	for(int i=2; i*i<=x; i++)
		if(x%i==0)
			return 0;
	return 1;
}

void prework()
{
	int mx=0;
	for(int i=B+1; i<=B+M; i++)
	{
		if(isprime(i))
			mx=i-1;
		g[i-B]=f(mx-B,i)+g[i-B-1];
	} 
}

LL calc(int x)
{
	if(x<=B)
		return 1LL*(1+x)*x/2;
	LL res1=1LL*(1+B)*B/2;
	LL res2=g[min(x,B+M)-B];
	if(x<=B+M)
		return res1+res2;
	LL res3=x-(B+M);
	return res1+res2+res3;
}

void mian()
{
	scanf("%d%d",&l,&r);
	printf("%lld\n",calc(r)-calc(l-1));
} 

int main()
{
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	
	scanf("%d%d",&T,&B);
	
	prework();
	while(T--)
		mian();

	return 0;
}
posted @   xishanmeigao  阅读(44)  评论(0编辑  收藏  举报
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示