zoukankan      html  css  js  c++  java
  • 【洛谷P3312】数表

    题目

    题目链接:https://www.luogu.com.cn/problem/P3312
    有一张 \(n\times m\) 的数表,其第 \(i\) 行第 \(j\) 列(\(1\le i\le n\)\(1\le j\le m\))的数值为能同时整除 \(i\)\(j\) 的所有自然数之和。给定 \(a\),计算数表中不大于 \(a\) 的数之和。

    思路

    先不考虑 \(a\) 的限制,那么 \((i,j)\) 的数值即为 \(\gcd(i,j)\) 的因子之和(设为 \(g(i)\))。\(g(i)\) 可以 \(O(n\log n)\) 预处理出。

    \[ans=\sum^{n}_{i=1}g(i)\times \sum^{\min(n,m)}_{d|i}\mu(\frac{i}{d})\lfloor{\frac{n}{i}}\rfloor\lfloor{\frac{m}{i}}\rfloor \]

    \[=\sum^{n}_{i=1}\lfloor{\frac{n}{i}}\rfloor\lfloor{\frac{m}{i}}\rfloor\sum^{\min(n,m)}_{i|d}g(d)\mu(\frac{i}{d}) \]

    当有 \(a\) 的限制时,只有 \(g(x)\leq a\)\(g(x)\) 才可以产生贡献。所以我们将询问按 \(a\) 排序,数字 \(x\)\(g(x)\) 排序,对于一个询问 \(a\)\(g(x)\leq a\) 的所有 \(g(x)\)\(x\) 倍数的贡献加上,然后再询问一段区间的和。
    用树状数组处理即可。然后就是整除分块乱搞了。
    时间复杂度 \(O(Q\sqrt{n}+Q\log^2 n)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned int uint;
    
    const int N=100010;
    int Q,tot,prm[N],mu[N],g[N];
    uint ans[N];
    bool v[N];
    
    struct Query
    {
    	int n,m,a,id;
    }ask[N];
    
    struct node
    {
    	int g,id;
    }a[N];
    
    bool cmp1(Query x,Query y)
    {
    	return x.a<y.a;
    }
    
    bool cmp2(node x,node y)
    {
    	return x.g<y.g;
    }
    
    void findprm(int n)
    {
    	mu[1]=1;
    	for (int i=2;i<=n;i++)
    	{
    		if (!v[i])
    			prm[++tot]=i,mu[i]=-1;
    		for (int j=1;j<=tot;j++)
    		{
    			if (i>n/prm[j]) break;
    			v[prm[j]*i]=1; mu[prm[j]*i]=-mu[i];
    			if (!(i%prm[j]))
    			{
    				mu[i*prm[j]]=0;
    				break;
    			}
    		}
    	}
    }
    
    struct BIT
    {
    	uint c[N];
    	
    	void add(int x,uint v)
    	{
    		for (int i=x;i<N;i+=i&-i)
    			c[i]+=v;
    	}
    	
    	uint query(int x)
    	{
    		uint ans=0;
    		for (int i=x;i;i-=i&-i)
    			ans+=c[i];
    		return ans;
    	}
    }bit;
    
    int main()
    {
    	findprm(N-10);
    	for (int i=1;i<=N-10;i++)
    		for (int j=i;j<=N-10;j+=i)
    			g[j]+=i;
    	for (int i=1;i<=N-10;i++)
    		a[i]=(node){g[i],i};
    	sort(a+1,a+1+N-10,cmp2);
    	scanf("%d",&Q);
    	for (int i=1;i<=Q;i++)
    	{
    		scanf("%d%d%d",&ask[i].n,&ask[i].m,&ask[i].a);
    		ask[i].id=i;
    	}
    	sort(ask+1,ask+1+Q,cmp1);
    	for (int i=1,j=1;i<=Q;i++)
    	{
    		for (;j<=N-10 && a[j].g<=ask[i].a;j++)
    			for (int k=a[j].id;k<=N-10;k+=a[j].id)
    				bit.add(k,1U*mu[k/a[j].id]*a[j].g);
    		int n=ask[i].n,m=ask[i].m;
    		for (int l=1,r;l<=min(n,m);l=r+1)
    		{
    			r=min(n/(n/l),m/(m/l));
    			ans[ask[i].id]+=1U*(n/l)*(m/l)*(bit.query(r)-bit.query(l-1));
    		}
    	}
    	for (int i=1;i<=Q;i++)
    		printf("%d\n",(int)(2147483647U&ans[i]));
    	return 0;
    }
    
  • 相关阅读:
    outline basic
    Best lua IDE
    Powershell core
    [转]ceph pg peering过程分析
    [转]ceph rbd到OSD的数据映射
    [转]ceph三种存储接口--块设备-文件系统-对象存储
    ceph monitor----paxos算法1
    ceph monitor----初始化和选举
    ceph monitor---总结1
    [转]ceph RADOS----概述
  • 原文地址:https://www.cnblogs.com/stoorz/p/13736808.html
Copyright © 2011-2022 走看看