zoukankan      html  css  js  c++  java
  • BZOJ4659: Lcm

    Description

    给出A,B,考虑所有满足l<=a<=A,l<=b<=B,且不存在n>1使得n^2同时整除a和b的有序数

    对(a,b),求其lcm(a,b)之和。答案模2^30。

    Input

    第一行一个整数T表示数据组数。接下来T行每行两个整数A,B表示一组数据。

    T ≤ 2000,A,B ≤ 4 × 10^6

    Output

    对每组数据输出一行一个整数表示答案模2^30的值

    Sample Input

    5
    2 2
    4 6
    3 4
    5 1
    23333 33333

    Sample Output

    7
    148
    48
    15
    451085813

    Solution

    (f(i))表示(i)有无平方因子(有为(0),否则为(1)

    那么题目的式子其实就是

    [sum_{i=1}^nsum_{j=1}^mlcm(i,j)f(gcd(i,j)) ]

    稍微用一下套路就可以化简到这步:

    (设(S(i)=sum_{i=1}^ni)

    [sum_{d=1}^n df(d)sum_{k=1}^{lfloor frac{n}{d} floor}mu(k)k^2S(lfloor frac{n}{kd} floor)S(lfloor frac{m}{kd} floor) ]

    (T=kd),换元可得

    [sum_{T=1}^nS(lfloor frac{n}{T} floor)S(lfloor frac{m}{T} floor)Tsum_{k|T}kmu(k)f(frac{T}{k}) ]

    后面显然是个积性函数(两个积性函数的点积与另一个积性函数的狄利克雷卷积)

    那么讨论一下来筛出来后面的就好了

    (g(i)=sum_{k|i}kmu(k)f(frac{i}{k}))

    (i=1)时,(g(i)=1)

    (iin prime)时,(g(i)=1-i)

    (i) 有平方质因子时,把平方质因子分离出来,手动展开一下就知道(g(p^2)=-p,g(p^c)=0(c>2))。所以分离出来平方质因子然后分类讨论一下就好

    复杂度(O(n+Tsqrt{n}))

    因为取模是对(2)的整数次幂取模,所以直接在最后与(2^{30}-1)取与即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    namespace io {
    char buf[1<<21], *p1 = buf, *p2 = buf;
    inline char gc() {
        if(p1 != p2) return *p1++;
        p1 = buf;
        p2 = p1 + fread(buf, 1, 1 << 21, stdin);
        return p1 == p2 ? EOF : *p1++;
    }
    #define G gc
    
    #ifndef ONLINE_JUDGE
    #undef G
    #define G getchar
    #endif
    
    template<class I>
    inline void read(I &x) {
        x = 0; I f = 1; char c = G();
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = G(); }
        while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = G(); }
        x *= f;
    }
    
    template<class I>
    inline void write(I x) {
        if(x == 0) {putchar('0'); return;}
        I tmp = x > 0 ? x : -x;
        if(x < 0) putchar('-');
        int cnt = 0;
        while(tmp > 0) {
            buf[cnt++] = tmp % 10 + '0';
            tmp /= 10;
        }
        while(cnt > 0) putchar(buf[--cnt]);
    }
    
    #define in(x) read(x)
    #define outn(x) write(x), putchar('
    ')
    #define out(x) write(x), putchar(' ')
    
    } using namespace io;
    
    #define ll long long
    const int N = 4000100;
    const ll mod = (1 << 30);
    
    ll g[N];
    int n, m;
    int cnt, p[N / 10], vis[N], tot[N], lev[N];
    
    void init() {
        g[1] = 1;
        for(int i = 2; i < N; ++i) {
            if(!vis[i]) {
                p[++cnt] = i;
            	g[i] = 1LL - i;
            	lev[i] = i;
            	tot[i] = 1;
    		}
            for(int j = 1; j <= cnt && i * p[j] < N; ++j) {
                vis[i * p[j]] = 1;
                if(i % p[j] == 0) {
                	lev[i * p[j]] = lev[i] * p[j];
                	tot[i * p[j]] = tot[i] + 1;
                	int tmp = i / lev[i];
         			if(tot[i * p[j]] == 2) g[i * p[j]] = g[tmp] * (-p[j]);
         			else g[i * p[j]] = 0;
    	 	       	break;
                }
            	g[i * p[j]] = g[i] * g[p[j]];
            	lev[i * p[j]] = p[j];
            	tot[i * p[j]] = 1;
    		}
        }
        for(int i = 1; i < N; ++i) g[i] = (i * g[i] + g[i - 1]); 
    }
    
    ll c1(ll n) {
    	return 1LL * n * (n + 1LL) / 2LL;
    }
    
    int main() {
        int T;
        read(T);
        init();
        while(T--) {
            ll ans = 0;
            read(n), read(m);
            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 = (ans + c1(n / l) * c1(m / l) * (g[r] - g[l - 1])); 
            }
            outn(ans & (mod - 1));
        }
    }
    
  • 相关阅读:
    TH-Union教学机 指令总结
    Manjaro 显卡驱动安装
    grub学习内容
    manjaro 折腾
    链栈的实现
    汇编综合实验
    二叉树
    Oracle表空间基本操作
    Windows7/10实现ICMP(ping命令)
    WireShark——IP协议包分析(Ping分析IP协议包)
  • 原文地址:https://www.cnblogs.com/henry-1202/p/11138145.html
Copyright © 2011-2022 走看看