• 【bzoj3518】点组计数 欧拉函数(欧拉反演)


    题目描述

    平面上摆放着一个n*m的点阵(下图所示是一个3*4的点阵)。Curimit想知道有多少三点组(a,b,c)满足以a,b,c三点共线。这里a,b,c是不同的3个点,其顺序无关紧要。(即(a,b,c)和
    (b,c,a)被认为是相同的)。由于答案很大,故你只需要输出答案对1,000,000,007的余数就可以了。

    输入

    有且仅有一行,两个用空格隔开的整数n和m。

    输出

    有且仅有一行,一个整数,表示三点组的数目对1,000,000,007的余数。(1,000。000。007是质数)

    样例输入

    3 4

    样例输出

    2 0


    题解

    欧拉函数(欧拉反演)

    先单独考虑横着的和竖着的,答案分别为 $m·C_n^3$ 和 $n·C_m^3$ 。

    然后考虑斜着的:设第一个点和第三个点横坐标差为 $i$ ,纵坐标差为 $j$ ,那么它们中间就有 $gcd(i,j)-1$ 个点,所以第二个点的个数就是 $gcd(i,j)-1$ ;又因为这样的矩形有 $(n-i)(m-j)$ 个,每个矩形有2个,因此总个数就是 $2(n-i)(m-j)gcd(i,j)$ 。

    因此斜着的答案就是:

    $sumlimits_{i=1}^{n-1}sumlimits_{j=1}^{m-1}2(n-i)(m-j)gcd(i,j)=2sumlimits_{d=1}^{min(n-1,m-1)}varphi(d)sumlimits_{i=1}^{lfloorfrac {n-1}d floor}(n-di)sumlimits_{j=1}^{lfloorfrac {m-1}d floor}(m-dj)$

    快筛 $varphi$ ,枚举 $d$ ,后面的两个 $sum$ 用等差数列求和公式 $O(1)$ 求出。

    时间复杂度 $O(n)$ 

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 50010
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    int phi[N] , prime[N] , tot , np[N];
    int main()
    {
    	int n , m , i , j;
    	ll ans;
    	scanf("%d%d" , &n , &m) , ans = ((ll)n * (n - 1) * (n - 2) / 6 % mod * m + (ll)m * (m - 1) * (m - 2) / 6 % mod * n) % mod;
    	if(n > m) swap(n , m);
    	n -- , m -- ;
    	phi[1] = 1;
    	for(i = 2 ; i <= n ; i ++ )
    	{
    		if(!np[i]) phi[i] = i - 1 , prime[++tot] = i;
    		for(j = 1 ; j <= tot && i * prime[j] <= n ; j ++ )
    		{
    			np[i * prime[j]] = 1;
    			if(!(i % prime[j]))
    			{
    				phi[i * prime[j]] = phi[i] * prime[j];
    				break;
    			}
    			else phi[i * prime[j]] = phi[i] * phi[prime[j]];
    		}
    	}
    	for(i = 1 ; i <= n ; i ++ )
    		ans = (ans + (ll)(n - i + 1 + n - n / i * i + 1) * (n / i) / 2 % mod * (m - i + 1 + m - m / i * i + 1) % mod * (m / i) % mod * phi[i]) % mod;
    	printf("%lld
    " , (ans - (ll)n * (n + 1) / 2 % mod * m % mod * (m + 1) % mod + mod) % mod);
    	return 0;
    }
    

     

  • 相关阅读:
    记一次JAVA WEB项目解决XSS攻击的办法(亲测有效)
    常用oracle可重复执行的脚本模板
    mybatis配置文件查询参数的传递
    oracle xmltype导入并解析Excel数据 (五)中间表数据入库
    oracle xmltype导入并解析Excel数据 (四)特别说明
    oracle xmltype导入并解析Excel数据 (三)解析Excel数据
    oracle xmltype导入并解析Excel数据 (二)规则说明
    oracle xmltype导入并解析Excel数据 (一)创建表与序
    ipv4,ipv6起止地址判断,网段判断
    HTML li标签排列有空白间隙
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8110864.html
Copyright © 2020-2023  润新知