• 【洛谷P6860】象棋与马


    题目

    题目链接:https://www.luogu.com.cn/problem/P6860
    Amazing John 有一个无限大的棋盘来下马棋。

    有一个马最开始在 ((0,0)),它的每一步可以走一个 (a imes b) 的矩形( 即能够从((x,y))到达 ((xpm a,ypm b))((xpm b,ypm a)) )。

    若马通过上述移动方式可以到达棋盘中任意一个点,那么 (p(a,b)=1),否则 (p(a,b)=0)

    现在 Amazing John 给你 (T) 组询问,每组询问他会给出一个正整数 (n),他想知道

    [left ( sum_{a=1}^nsum_{b=1}^np(a,b) ight )mod 2^{64} ]

    的值。

    思路

    [mathrm{Qcolor{red}{uantAsk} YYDS!} ]

    显然马可以走到任意点的充要条件就是可以走到 ((1,0))。我们可以列出马可以走到的点的集合,容易得出它可以走到 ((1,0)) 的充要条件是 (gcd(a,b)=1)(a+b) 是奇数。这个条件等价于 (gcd(a,b)=1)(a-b) 是奇数。
    如果 (a) 是偶数,那么显然任意小于 (a) 且与 (a) 互质的数都满足 (a-b) 是奇数,所以此时合法的 (b) 的数量就是 (varphi(a))
    如果 (a) 是奇数,如果 (gcd(a,b)=1),那么 (gcd(a-b)) 显然也是 (1),而 (b)(a-b) 中恰好是一奇一偶,所以任意一个与 (a) 互质的奇数都对应一个与 (a) 互质的偶数,所以此时合法的 (b) 的数量是 (frac{varphi(a)}{2})
    所以答案就是

    [sum^{ileq n,iin mathrm{odd}}_{i=1}varphi(i)+sum^{ileq n,iinmathrm{even}}_{i=2}2varphi(i)-1 ]

    要乘二的原因是对于 (p(a,b))(p(b,a)) 两组合法解,我们只计算了其中一种(也就是 (a>b) 那种)。而减一则是因为 (p(1,1)) 被计算了,要舍去。
    考虑怎么计算上述式子。假设我们已经求出了 ([1,n]) 中,偶数的 (varphi) 和奇数的 (varphi) 各自的和,我们需要将它扩展到 ([1,2n])
    对于任意的奇数 (x),它乘二之后会变成偶数。假设原来 (varphi(x)=x imes frac{p_1-1}{p_1} imes frac{p_2-1}{p_2}cdots),由于 (2) 是一个 (x) 之前没有的因子,所以 (varphi(2x)=2x imes frac{p_1-1}{p_1} imes frac{p_2-1}{p_2}cdots imes frac{1}{2}),依然等于 (varphi(x))
    对于任意的偶数 (x),它乘二之后并没有多出任何之前不存在的质因子,所以 (varphi(2x)=2x imes frac{p_1-1}{p_1} imes frac{p_2-1}{p_2}cdots=2varphi(x))
    所以 ([1,2n]) 中偶数的 (varphi) 之和等于 (s_{odd}+2s_{even})
    然后我们用杜教筛求出 ([1,2n]) 所有数的 (varphi) 之和,用该值减去偶数的 (varphi) 之和就得到了奇数的 (varphi) 之和。再回溯计算即可。
    时间复杂度 (O(Tn^{frac{2}{3}}log n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    
    const int N=1e7+10;
    int Q,m,prm[N];
    ull n,s1,s2,phi[N];
    bool v[N];
    map<int,ull> sphi;
    
    void findprm(int n)
    {
    	phi[1]=1;
    	for (int i=2;i<=n;i++)
    	{
    		if (!v[i]) prm[++m]=i,phi[i]=i-1;
    		for (int j=1;j<=m;j++)
    		{
    			if (i>n/prm[j]) break;
    			v[i*prm[j]]=1; phi[i*prm[j]]=phi[i]*(prm[j]-1);
    			if (i%prm[j]==0)
    			{
    				phi[i*prm[j]]=phi[i]*prm[j];
    				break;
    			}
    		}
    	}
    }
    
    ull sumphi(ull n)
    {
    	if (n<N) return phi[n];
    	if (sphi[n]) return sphi[n];
    	ull res=114514;
    	if (n&1ULL) res=(n+1ULL)/2ULL*n;
    		else res=n/2ULL*(n+1ULL);
    	for (ull l=2,r;l<=n;l=r+1)
    	{
    		r=n/(n/l);
    		res-=sumphi(n/l)*(r-l+1);
    	}
    	return sphi[n]=res;
    }
    
    void calc(ull n,ull &s1,ull &s2)
    {
    	if (n==1)
    	{
    		s1=1; s2=0;
    		return;
    	}
    	calc(n/2ULL,s1,s2);
    	s2=s1+s2*2ULL; s1=sumphi(n)-s2;
    }
    
    int main()
    {
    	findprm(N-1);
    	for (int i=1;i<N;i++)
    		phi[i]=phi[i-1]+phi[i];
    	scanf("%d",&Q);
    	while (Q--)
    	{
    		cin>>n;
    		calc(n,s1,s2);
    		cout<<s1+s2*2ULL-1ULL<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    运用jQuery实现动态点赞
    $scope作用及模块化解决全局问题
    angular数据绑定---js全局学习
    HDU 2102 A计划 (深搜)
    ffmpeg 常用命令汇总
    基于Red5与ffmpeg实现rtmp处理NVR或摄像头的监控视频处理方案
    Linux 下编写.sh文件运行JAR下的Class
    如何帮助团队完成一个优秀的API文档,Swagger和Spring Rest Docs两个都是十分优秀的工具!...
    你关心的学历问题在这里
    北京一二线大厂以及程序员层级分布
  • 原文地址:https://www.cnblogs.com/stoorz/p/14086012.html
Copyright © 2020-2023  润新知