zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    软件工程第一次作业
    7.9-7.22日团队进展及博客更新状况
    2018 软件工程暑期培训小结
    结对编程(第7组)
    6.3日前团队项目打分情况
    第六周实践作业:软件测试和评估
    第4周小组作业:WordCount优化
    第2周个人作业:WordCount
    博客阅读和思考
    个人总结
  • 原文地址:https://www.cnblogs.com/mogeko/p/13360701.html
Copyright © 2011-2022 走看看