zoukankan      html  css  js  c++  java
  • HDU4746 Mophues

    题目地址

    题目链接

    Description

     As we know, any positive integer C ( C >= 2 ) can be written as the multiply of some prime numbers:
        C = p1×p2× p3× ... × pk
    which p1, p2 ... pk are all prime numbers.For example, if C = 24, then:
        24 = 2 × 2 × 2 × 3
        here, p1 = p2 = p3 = 2, p4 = 3, k = 4
    
    Given two integers P and C. if k<=P( k is the number of C's prime factors), we call C a lucky number of P.
    
    Now, XXX needs to count the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of a given P ( "gcd" means "greatest common divisor").
    
    Please note that we define 1 as lucky number of any non-negative integers because 1 has no prime factor. 
    

    Input

    The first line of input is an integer Q meaning that there are Q test cases.
    Then Q lines follow, each line is a test case and each test case contains three non-negative numbers: n, m and P (n, m, P <= 5×10 5. Q <=5000).
    

    Output

    For each test case, print the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of P.
    

    Sample Input

    2
    10 10 0
    10 10 1
    

    Sample Output

    63
    93
    

    Solution

    神仙结论。不过其实不难想。。。但是我不看题解很难想到。
    首先大力推式子但是我懒得写推导在这里了意会一下吧,写到这道题应该也不难推到这里=_=

    [sum_{T=1}^nfrac{n}{T}frac{m}{T}sum_{d|T}mu(frac{T}{d})[h(d)<=p] ]

    但是这个(h(d))怎么解决真的不知道。。。p是每次给定的啊。。。
    于是抄题解,领会到了神仙们的神仙思维多么强大。
    (2^{18})就大于(500000)了,所以(h(i))一定都小于18,对于p大于18的,表达式一定恒为真,前缀和预处理前p<=18的情况就好了。。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 500010;
    #define ll long long
    int mu[N], T, p[N], cnt;
    int h[N], sum[20][N], P;
    bool vis[N]; 
    ll n, m;
    
    void init() {
    	mu[1] = 1;
    	for(int i = 2; i < N; ++i) {
    		if(!vis[i]) p[++cnt] = i, mu[i] = -1, h[i] = 1;
    		for(int j = 1; j <= cnt && i * p[j] < N; ++j) {
    			vis[i * p[j]] = 1;
    			h[i * p[j]] = h[i] + 1;
    			if(i % p[j] == 0) break;
    			mu[i * p[j]] = -mu[i]; 
    		}
    	} 
    	for(int i = 1; i < N; ++i) 
    		for(int j = i; j < N; j += i) 
    			sum[h[i]][j] += mu[j / i];
    	for(int k = 0; k <= 18; ++k) 
    		for(int i = 1; i < N; ++i)
    			sum[k][i] += sum[k][i - 1];
    	for(int j = 1; j <= 18; ++j) 
    		for(int i = 1; i < N; ++i) 
    			sum[j][i] += sum[j - 1][i];
    }
    
    ll calc(ll n, ll m, ll lim) {
    	ll ans = 0;
    	if(n > m) swap(n, m);
    	for(ll l = 1, r; l <= n; l = r + 1) {
    		r = min(n / (n / l), m / (m / l));
    		ans += 1ll * (sum[lim][r] - sum[lim][l - 1]) * (n / l) * (m / l);
    	}
    	return ans;
    }
    
    int main() {
    	init();
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%lld%lld%d", &n, &m, &P);
    		if(P > 18) printf("%lld
    ", n * m);
    		else printf("%lld
    ", calc(n, m, P));
    	}
    	return 0;
    }
    
  • 相关阅读:
    简单马周游问题1152siicly
    Sicily 1155. Can I Post the lette
    POJ 1007
    给定2个大小分别为n, m的整数集合,分别存放在两个数组中 int A[n],B[m],输出两个集合的交集。
    算法1--
    GAN
    为什么ConcurrentHashMap是弱一致的
    手写HASHMAP
    千万级规模高性能、高并发的网络架构经验分享
    Web 通信 之 长连接、长轮询(转)
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10351217.html
Copyright © 2011-2022 走看看