【bzoj3529】 Sdoi2014—数表

μhttp://www.lydsy.com/JudgeOnline/problem.php?id=3529 (题目链接)

题意

  多组询问,每次给出${n,m,a}$。求$${\sum_{i=1}^n\sum_{j=1}^m[\sum_{d|i,d|j}d<=a]\sum_{d|i,d|j}d}$$

Solution

  PoPoQQQ的看不懂,我还是比较适合套路→_→:http://blog.csdn.net/FZHvampire/article/details/50964639

  有${a}$的限制很不好做,我们不妨先来看看如果没有${a}$的限制,是个什么情况。

\begin{aligned}  & \sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}d  \\  =&\sum_{i=1}^n\sum{j=1}^m\sum_{d=1}^{min(n,m)}f(d)[gcd(i,j)=d]   \end{aligned}

  这里${f(d)}$表示${d}$的约数和,由约数和定理:$${d=p_1^{a_1}p_2^{a_2}p_3^{a_3}······p_k^{a_k}}$$

$${f(d)=(p_1^0+p_1^1+······+p_1^{a_1})(p_2^0+p_2^1+······+p_2^{a_2})······(p_k^0+p_k^1+······+p_k^{a_k})}$$

  我们发现当${p,q}$互质时,${f(pq)=f(p)f(q)}$,${f}$是个积性函数。也就是说${f}$可以线性筛求解,具体求法可以看代码。回到上面的问题,我们继续变化这个式子。

\begin{aligned}  &\sum_{i=1}^n\sum_{j=1}^m\sum_{d=1}^{min(n,m)}f(d)[gcd(i,j)=d]  \\  =&\sum_{d=1}^{min(n,m)}f(d)\sum_{i=1}^{\lfloor{n/d}\rfloor}\sum_{j=1}^{\lfloor{m/d}\rfloor}[gcd(i,j)=1]  \\  =&\sum_{d=1}^{min(n,m)}f(d)\sum_{t=1}^{min(\lfloor{n/d}\rfloor,\lfloor{m/d}\rfloor)}μ(t)\lfloor\frac{n}{dt}\rfloor\lfloor\frac{m}{dt}\rfloor   \end{aligned}

  我们令${Q=dt}$,先枚举${Q}$,得到:$${\sum_{Q=1}^{min(n,m)}\lfloor\frac{n}{Q}\rfloor\lfloor\frac{m}{Q}\rfloor\sum_{d|Q}f(d)μ(\frac{Q}{d})}$$

  我们对${f}$和${μ}$函数的狄利克雷卷积${g(Q)=\sum_{d|Q}f(d)μ(\frac{Q}{d})}$预处理前缀和,前面的${\lfloor\frac{n}{Q}\rfloor\lfloor\frac{m}{Q}\rfloor}$分块,那么这个式子的计算就达到了${\sqrt{n}}$。

  考虑如何加入限制${a}$。

  我们可以离线,将询问按照${a}$从小到大排序,${f}$函数按照从小到大排序。询问的时候,我们就动态维护一个树状数组${c}$。树状数组的每一位${c[x]}$存的是卷积${g(x)}$中${f(d)}$不超过${a}$的数之和。数据组数为${T}$,询问复杂度${O(T\sqrt{n}logn)}$

细节

  这题复杂度有点卡,对于取模运算我们可以对${int}$自然溢,最后再${\&2147483647}$就可以了。

代码

// bzoj3994
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#define LL long long
#define inf 2147483647
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

const int maxn=100010;
int mu[maxn],e[maxn],ans[maxn],c[maxn],vis[maxn],p[maxn],t[maxn],g[maxn];

struct F {int d,num;}f[maxn];
struct Q {int n,m,a,id;}q[maxn];

bool cmpT(Q a,Q b) {return a.a<b.a;}
bool cmpt(F a,F b) {return a.d<b.d;}
int lowbit(int x) {return x&-x;}
int power(int a,int b) {
	int res=1;
	while (b) {
		if (b&1) res*=a;
		a*=a,b>>=1;
	}
	return res;
}
void add(int x,int val) {
	for (int i=x;i<maxn;i+=lowbit(i)) c[i]+=val;
}
int query(int x) {
	int s=0;
	for (int i=x;i>=1;i-=lowbit(i)) s+=c[i];
	return s;
}
int main() {
	mu[1]=1;f[1].d=f[1].num=1;
	for (int i=2;i<maxn;i++) {
		f[i].num=i;
		if (!vis[i]) mu[i]=-1,f[i].d=t[i]=1+i,g[i]=1,p[++p[0]]=i;
		for (int j=1;j<=p[0] && i*p[j]<maxn;j++) {
			vis[i*p[j]]=1;
			if (i%p[j]==0) {
				mu[i*p[j]]=0;
				g[i*p[j]]=g[i]+1;
				t[i*p[j]]=t[i]+power(p[j],g[i]+1);
				f[i*p[j]].d=f[i].d/t[i]*t[i*p[j]];
				break;
			}
			else {
				mu[i*p[j]]=-mu[i];
				f[i*p[j]].d=f[i].d*f[p[j]].d;
				g[i*p[j]]=1;t[i*p[j]]=p[j]+1;
			}
		}
	}
	int T;scanf("%d",&T);
	for (int i=1;i<=T;i++) scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a),q[i].id=i;
	sort(q+1,q+1+T,cmpT);
	sort(f+1,f+maxn,cmpt);
	for (int now=0,i=1;i<=T;i++) {
		while (now<maxn && f[now+1].d<=q[i].a) {
			now++;
			for (int j=1;j*f[now].num<maxn;j++)
				add(j*f[now].num,mu[j]*f[now].d);
		}
		int n=q[i].n,m=q[i].m;
		if (n>m) swap(n,m);
		for (int j=1,k;j<=n;j=k+1) {
			k=min(n/(n/j),m/(m/j));
			ans[q[i].id]+=(n/j)*(m/j)*(query(k)-query(j-1));
		}
		ans[q[i].id]&=inf;
	}
	for (int i=1;i<=T;i++) printf("%d\n",ans[i]);
	return 0;
}
时间: 2024-08-03 07:00:56

【bzoj3529】 Sdoi2014—数表的相关文章

[bzoj3529][Sdoi2014]数表_树状数组_莫比乌斯反演

数表 bzoj-3529 Sdoi-2014 题目大意:n*m的数表,第i行第j列的数是同时整除i和j的所有自然数之和.给定a,求数表中所有不超过a的和. 注释:$1\le n,m \le 10^5$. 想法:我们先不考虑那个a的限制:我们设f(i)表示整除i的自然数之和. $\sum\limits_{i=1}^n\sum\limits_{j=1}^m f(gcd(i,j))$ $\sum\limits_{i=1}^n\sum\limits_{j=1}^m f(d)\cdot [gcd(i,j)

[BZOJ3529][Sdoi2014]数表

试题描述 有一张N×m的数表,其第i行第j列(1 < =i < =n,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. 输入 输入包含多组数据.输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据. 输出 对每组数据,输出一行一个整数,表示答案模2^31的值. 输入示例 2 4 4 3 10 10 5 输出示例 20 148 数据规模及约定 1 < =

【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组

[BZOJ3529][Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. Input 输入包含多组数据.    输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据. Output 对每组数据,输出一行一个整数,表示答案模2^31的值. Sample I

BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status][Discuss] Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. Input 输入包含多组数据.    输入的第一行一个整数Q表示测试点内的数据

P3312 [SDOI2014]数表

P3312 [SDOI2014]数表 求\(\sum_{i=1}^n\sum_{j=1}^m\sigma(gcd(i,j))[\sigma(gcd(i,j)<=a)]\) \(f(d)=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d]\) \(F(d)=\sum_{i=1}^n\sum_{j=1}^m [|dgcd(i,j)]=\sum_{d|k}f(k)\) \(f(d)=\sum_{d|k}\mu(\dfrac{k}{d})F(k)=\sum_{d|k}\mu(\le

bzoj [SDOI2014]数表 莫比乌斯反演 BIT

bzoj [SDOI2014]数表 莫比乌斯反演 BIT 链接 bzoj luogu loj 思路 \[ \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}a*[f[gcd(i,j)]<=a] \] \[ f[]可以O(n)预处理出来 \] \[ \sum\limits_{k=1}^{n}f[k]*\sum\limits_{i=1}^{m}\sum\limits_{j=1}^{m}[gcd(i,j)==k] \] \[ \sum\limits_{k=1}^{n}

【SDOI2014】【BZOJ3529】数表

Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼.1 < =j < =m)的数值为 能同一时候整除i和j的全部自然数之和.给定a,计算数表中不大于a的数之和. Input 输入包括多组数据. 输入的第一行一个整数Q表示測试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描写叙述一组数据. Output 对每组数据,输出一行一个整数.表示答案模2^31的值. Sample Input 2 4 4 3 10 10 5

【BZOJ3529】【莫比乌斯反演 + 树状数组】[Sdoi2014]数表

Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. Input 输入包含多组数据.     输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据. Output 对每组数据,输出一行一个整数,表示答案模2^31的值. Sample Input 2 4 4 3 10 10 5

[bzoj3529] [洛谷P3312] [Sdoi2014] 数表

Description 有一张n×m的数表,其第i行第j列(1 < =i < =n,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. Input 输入包含多组数据. 输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据. Output 对每组数据,输出一行一个整数,表示答案模2^31的值. Sample Input 2 4 4 3 10 10 5 Samp