zoukankan      html  css  js  c++  java
  • P4449 于神之怒加强版

    (color{#0066ff}{ 题目描述 })

    给定n,m,k,计算

    (sum_{i=1}^n sum_{j=1}^m mathrm{gcd}(i,j)^k)

    对1000000007取模的结果

    (color{#0066ff}{输入格式})

    多组数据。 第一行是两个数T,K; 之后的T行,每行两个整数n,m;

    (color{#0066ff}{输出格式})

    K行,每行一个结果

    (color{#0066ff}{输入样例})

    1 2
    3 3
    

    (color{#0066ff}{输出样例})

    20
    

    (color{#0066ff}{数据范围与提示})

    T<=2000,1<=N,M,K<=5000000

    (color{#0066ff}{ 题解 })

    就是要求

    [sum_{i=1}^n sum_{j=1}^m gcd(i,j)^k ]

    枚举gcd

    [sum_{d=1}^{min(n,m)}sum_{i=1}^n sum_{j=1}^m [gcd(i,j)==d]d^k ]

    (d^k)提出来,d再除上去,就是一个基本模型了

    [sum_{d=1}^{min(n,m)}d^ksum_{i=1}^{lfloorfrac{n}{d} floor} sum_{j=1}^{lfloorfrac{m}{d} floor} [gcd(i,j)==1] ]

    [sum_{d=1}^{min(n,m)}d^ksum_{i=1}^{lfloorfrac{n}{d} floor} sum_{j=1}^{lfloorfrac{m}{d} floor} sum_{k|gcd(i,j)} mu(k) ]

    [sum_{d=1}^{min(n,m)}d^ksum_{k=1}^{min(lfloorfrac{n}{d} floor,lfloorfrac{m}{d} floor)}mu(k)sum_{i=1}^{lfloorfrac{n}{kd} floor} sum_{j=1}^{lfloorfrac{m}{kd} floor} 1 ]

    后面好像空了。。。

    [sum_{d=1}^{min(n,m)}d^ksum_{k=1}^{min(lfloorfrac{n}{d} floor,lfloorfrac{m}{d} floor)}mu(k) * lfloorfrac{n}{kd} floor * lfloorfrac{m}{kd} floor ]

    来一发kd换q

    [sum_{q=1}^{min(n,m)} lfloorfrac{n}{q} floor * lfloorfrac{m}{q} floor sum_{d|q}mu(frac q d)*d^k ]

    “额,这怎么处理”

    “暴力了解一下”

    线性筛出(mu) 然后(O(nlogn))求出(d^k)

    之后枚举倍数(O(nlogn)把后面的)sum$搞出来,数列分块就行了

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const int mod = 1e9 + 7;
    const int maxn = 5e6 + 100;
    int k;
    int mu[maxn], pri[maxn], tot, mi[maxn];
    bool vis[maxn];
    LL h[maxn];
    LL ksm(LL x, LL y) {
    	LL re = 1LL;
    	while(y) {
    		if(y & 1) re = re * x % mod;
    		x = x * x % mod;
    		y >>= 1;
    	}
    	return re;
    }
    void predoit() {
    	mu[1] = 1;
    	for(int i = 2; i < maxn; i++) {
    		if(!vis[i]) pri[++tot] = i, mu[i] = -1;
    		for(int j = 1; j <= tot && (LL)i * pri[j] < maxn; j++) {
    			vis[i * pri[j]] = true;
    			if(i % pri[j] == 0) break;
    			else mu[i * pri[j]] = -mu[i];
    		}
    	}
    	for(int i = 1; i < maxn; i++) mi[i] = ksm(i, k);
    	for(int i = 1; i < maxn; i++)
    		for(int j = i; j < maxn; j += i)
    			(h[j] += (1LL * mu[j / i] * mi[i] % mod)) %= mod;
    	for(int i = 2; i < maxn; i++) (h[i] += h[i - 1]) %= mod;
    }
    LL work(LL n, LL m) {
    	LL ans = 0;
    	for(LL l = 1, r; l <= std::min(n, m); l = r + 1) {
    		r = std::min(n / (n / l), m / (m / l));
    		LL tot1 = (n / l) * (m / l) % mod;
    		tot1 = (tot1 * ((h[r] - h[l - 1]) % mod + mod) % mod) % mod;
    		(ans += tot1) %= mod;
    	}
    	return ans;
    }
    int main() {
    	int T;
    	for(T = in(), k = in(), predoit(); T --> 0;)
    		printf("%lld
    ", work(in(), in()));
    	return 0;
    }
    
  • 相关阅读:
    Java线程优先级(Priority)
    Java同步锁(synchronized)、锁(lock)以及死锁
    Java实现多线程的三种方式(3) ------实现Callable<V>接口
    Java实现多线程的三种方式(2) ------实现Runnable接口
    Java实现多线程的三种方式(1) ------继承Thread类
    Spring AOP(2) --基于配置文件方式配置
    Spring AOP(1) --基于注解方式配置
    Spring IOC容器基于注解方式装配Bean
    Spring IOC容器基于配置文件装配Bean(9) ------bean的SpEL用法
    Python基础教程学习目录
  • 原文地址:https://www.cnblogs.com/olinr/p/10301794.html
Copyright © 2011-2022 走看看