zoukankan      html  css  js  c++  java
  • 【Luogu P2522】 [HAOI2011]Problem b

    题目链接:

    题目

    博客园

    题目大意:

    快速求:

    [sum_{i=a}^{b}sum_{j=c}^{d}left[operatorname{gcd}(i,j)==d ight] ]

    正文:

    这道题和 [POI2007]ZAP-Queries 思路一样,先化简再整除分块。但是这题不能直接化,先考虑 (a=1,c=1) 的情况,用二维前缀和的思想得到答案。

    代码:

    
    ll n, m, n1, m1, d, t;
    ll pri[N], miu[N], cnt, sum[N];
    bool vis[N];
    
    void prework()
    {
    	miu[1] = 1;
    	for (int i = 2; i <= N - 10; i++)
    	{
    		if(!vis[i]) {pri[++cnt] = i, miu[i] = -1;}
    		for (int j = 1; j <= cnt && pri[j] * i <= N - 10; j++)
    		{
    			vis[pri[j] * i] = 1;
    			if (i % pri[j] == 0)
    			{
    				miu[i * pri[j]] = 0;
    				break;
    			}
    			else
    				miu[i * pri[j]] = -miu[i];
    		}
    	}
    	for (int i = 1; i <= N - 10; i++)
    		sum[i] = sum[i - 1] + miu[i];
    }
    ll Ans(int n, int m)
    {
    	ll ans = 0;
    	if(n > m)
    	{
    		int c = n; n = m; m = c;
    	}
    	n /= d, m /= d;
    	for (int l = 1, r; l <= n; l = r + 1)
    	{
    		r = min (n / (n / l), m / (m / l));
    		ans += (sum[r] - sum[l - 1]) * (n / l) * (m / l);
    	}
    	return ans;
    }
    
    int main()
    {
    	prework();
    	for (scanf ("%lld", &t); t--; )
    	{
    		scanf("%lld%lld%lld%lld%lld", &n, &m, &n1, &m1, &d);
    		printf("%lld
    ", Ans(m, m1) - Ans(m, n1 - 1) - Ans(n - 1, m1) + Ans(n1 - 1, n - 1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    强连通分量(Kosaraju)
    拓扑排序
    树状数组BIT
    差分
    RMQ(ST表)
    LCA(Tarjan)
    LCA(ST倍增)
    海亮SC2019 树上数数(转载)
    海亮SC
    【十二省联考2019】异或粽子/可持久化01trie
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/13603496.html
Copyright © 2011-2022 走看看