• Luogu P3312 [SDOI2014]数表


    gate

    (sigma(i))表示(i)的因子之和。
    (sumlimits_{i=1}^nsumlimits_{j=1}^msigma(gcd(i,j)) [sigma(gcd(i,j))le a])
    (sumlimits_{k=1}^nsigma(k)sumlimits_{i=1}^{frac{n}{k}}sumlimits_{j=1}^{frac{m}{k}}sum_{d|gcd(i,j)}mu(d) [sigma(k)le a])
    (sumlimits_{k=1}^nsigma(k)sumlimits_{d=1}^{frac{n}{k}}mu(d)lfloorfrac{n}{kd} floorlfloorfrac{m}{kd} floor [sigma(k)le a])

    (T=kd)

    (sumlimits_{T=1}^nlfloorfrac{n}{T} floorlfloorfrac{m}{T} floorsum_{d|T}mu(d) imessigma(frac{T}{d}) [sigma(frac{T}{d})le a])

    (f(T,a) = sum_{d|T}mu(d) imessigma(frac{T}{d}) [sigma(frac{T}{d})le a])

    预处理出(sigma(x)).
    将询问离线,按(a)从小到大排序。
    每次遇到一个询问时,更新所有(sigma(x)<a)(x)的贡献。
    (sigma(x))会对(f(x,a),f(2x,a),f(3x,a),...)产生影响,贡献即为(mu(i)*sigma(x) (ix=T,x=frac{T}{i}))
    因为要求前缀和,(f(x))可以用树状数组维护。

    时间复杂度(O(n log^2 n +qsqrt n log n))
    吸氧可过

    code

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define MogeKo qwq
    using namespace std;
    
    const int maxn = 1e5+10;
    const int N = 1e5;
    const int mod = 1ll<<31;
    
    int Q,now,cnt;
    int prime[maxn],mu[maxn];
    long long sig[maxn],tree[maxn],ans[maxn];
    bool vis[maxn];
    
    struct node {
    	long long x,y,z,id;
    	bool operator < (const node &N) const {
    		return z < N.z;
    	}
    } q[maxn],d[maxn];
    
    long long read() {
    	long long x = 0,f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') f = -1;
    		ch = getchar();
    	}
    	while('0' <= ch && ch <= '9') {
    		x = x*10 + ch-'0';
    		ch = getchar();
    	}
    	return x*f;
    }
    
    void Prime() {
    	mu[1] = 1;
    	for(int i = 2; i <= N; i++) {
    		if(!vis[i]) {
    			prime[++cnt] = i;
    			mu[i] = -1;
    		}
    		for(int j = 1; j <= cnt && i*prime[j] <= N; j++) {
    			vis[i*prime[j]] = true;
    			if(i % prime[j] == 0) break;
    			mu[i*prime[j]] = -mu[i];
    		}
    	}
    	for(int i = 1; i <= N; i++) {
    		for(int j = 1; i*j <= N; j++)
    			sig[i*j] += i;
    		d[i].z = sig[i];
    		d[i].id = i;
    	}
    	sort(d+1,d+N+1);
    }
    
    int lowbit(int x) {
    	return x & (-x);
    }
    
    void add(int x,int k) {
    	for(; x <= N; x += lowbit(x))
    		tree[x] += k;
    }
    
    long long query(int x) {
    	long long num = 0;
    	for(; x; x -= lowbit(x))
    		num += tree[x];
    	return num;
    }
    
    void modify(int x) {
    	for(int i = 1; i*x <= N; i++)
    		add(i*x,mu[i]*sig[x]);
    }
    
    long long solve(int x,int y) {
    	int num = 0;
    	if(x > y) swap(x,y);
    	for(int i = 1,r; i <= x; i = r+1) {
    		r = min(x/(x/i), y/(y/i));
    		num += (long long)(x/i) * (y/i) * (query(r) - query(i-1));
    	}
    	return num % mod;
    }
    
    int main() {
    	Q = read();
    	for(int i = 1; i <= Q; i++) {
    		q[i].x = read(), q[i].y = read(), q[i].z = read();
    		q[i].id = i;
    	}
    	sort(q+1,q+Q+1);
    	Prime();
    	now = 0;
    	for(int i = 1; i <= Q; i++) {
    		while(d[now+1].z <= q[i].z && now < N)
    			modify(d[++now].id);
    		ans[q[i].id] = solve(q[i].x,q[i].y);
    	}
    	for(int i = 1; i <= Q; i++)
    		printf("%lld
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    第二章 金字塔内部的结构
    第一章 为什么要用金字塔结构
    考研级《计算机网络》知识梳理——第二期
    考研级《计算机网络》知识梳理——第一期
    leetcode常规算法题复盘(科普短文篇)——为何哈希表的容量一般是质数
    leetcode常规算法题复盘(第十六期)——数据流中的第 K 大元素
    leetcode常规算法题复盘(第十四期)——最后一块石头的重量
    leetcode常规算法题复盘(第十三期)——最大矩形&柱状图中最大的矩形
    leetcode常规算法题复盘(第十二期)——摆动序列&买卖股票的最佳时机含手续费
    leetcode常规算法题复盘(基础篇)——线性表java实现
  • 原文地址:https://www.cnblogs.com/mogeko/p/13360701.html
Copyright © 2020-2023  润新知