【SDOI2014】BZOJ3529 数表题解(Mobius反演+树状数组+除法分块)

  • Post author:
  • Post category:其他


题目:

BZOJ3529

.

题目大意:设



f

(

i

,

j

)

=

d

g

c

d

(

i

,

j

)

d

f(i,j)=\sum_{d|gcd(i,j)}d






f


(


i


,




j


)




=





















d





g


c


d


(


i


,


j


)





















d





,给定



Q

Q






Q





组询问,每次询问



n

,

m

,

a

n,m,a






n


,




m


,




a





,求



i

=

1

n

j

=

1

,

f

(

i

,

j

)

a

m

f

(

i

,

j

)

\sum_{i=1}^{n}\sum_{j=1,f(i,j)\leq a}^{m}f(i,j)



















i


=


1










n


































j


=


1


,


f


(


i


,


j


)





a










m





















f


(


i


,




j


)





.




1

n

,

m

1

0

5

,

1

q

2

1

0

4

,

1

a

1

0

9

1\leq n,m\leq 10^5,1\leq q\leq 2*10^4,1\leq |a|\leq 10^9






1













n


,




m













1



0










5









,




1













q













2













1



0










4









,




1
















a
















1



0










9












.

先考虑没有



a

a






a





限制的情况,那么:





i

=

1

n

j

=

1

m

f

(

i

,

j

)

=

i

=

1

n

j

=

1

m

d

g

c

d

(

i

,

j

)

d

=

d

=

1

m

i

n

(

n

,

m

)

(

t

d

t

)

(

i

=

1

n

j

=

1

m

[

g

c

d

(

i

,

j

)

=

d

]

)

\sum_{i=1}^{n}\sum_{j=1}^{m}f(i,j)\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|gcd(i,j)}d\\ =\sum_{d=1}^{min(n,m)}(\sum_{t|d}t)(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d])















i


=


1



















n





























j


=


1



















m




















f


(


i


,




j


)










=

















i


=


1



















n





























j


=


1



















m





























d





g


c


d


(


i


,


j


)





























d










=

















d


=


1



















m


i


n


(


n


,


m


)


















(











t





d





























t


)


(











i


=


1



















n





























j


=


1



















m


















[


g


c


d


(


i


,




j


)




=








d


]


)









σ

(

n

)

=

d

n

d

\sigma(n)=\sum_{d|n}d






σ


(


n


)




=





















d





n





















d





,那么:





d

=

1

m

i

n

(

n

,

m

)

(

t

d

t

)

(

i

=

1

n

j

=

1

m

[

g

c

d

(

i

,

j

)

=

d

]

)

=

d

=

1

m

i

n

(

n

,

m

)

σ

(

d

)

i

=

1

n

j

=

1

m

[

g

c

d

(

i

,

j

)

=

d

]

=

d

=

1

m

i

n

(

n

,

m

)

σ

(

d

)

i

=

1

n

d

j

=

1

m

d

[

g

c

d

(

i

,

j

)

=

1

]

=

d

=

1

m

i

n

(

n

,

m

)

σ

(

d

)

i

=

1

n

d

j

=

1

m

d

t

i

t

j

μ

(

t

)

=

d

=

1

m

i

n

(

n

,

m

)

σ

(

d

)

t

=

1

m

i

n

(

n

,

m

)

d

μ

(

t

)

n

d

t

m

d

t

\sum_{d=1}^{min(n,m)}(\sum_{t|d}t)(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d])\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d]\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[gcd(i,j)=1]\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}\sum_{t|i\wedge t|j}\mu(t)\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{t=1}^{\left\lfloor\frac{min(n,m)}{d}\right\rfloor}\mu(t)\left\lfloor\frac{n}{dt}\right\rfloor\left\lfloor\frac{m}{dt}\right\rfloor















d


=


1



















m


i


n


(


n


,


m


)


















(











t





d





























t


)


(











i


=


1



















n





























j


=


1



















m


















[


g


c


d


(


i


,




j


)




=








d


]


)










=

















d


=


1



















m


i


n


(


n


,


m


)




















σ


(


d


)













i


=


1



















n





























j


=


1



















m


















[


g


c


d


(


i


,




j


)




=








d


]










=

















d


=


1



















m


i


n


(


n


,


m


)




















σ


(


d


)













i


=


1





































d
















n






















































j


=


1





































d
















m











































[


g


c


d


(


i


,




j


)




=








1


]










=

















d


=


1



















m


i


n


(


n


,


m


)




















σ


(


d


)













i


=


1





































d
















n






















































j


=


1





































d
















m






















































t





i





t





j





























μ


(


t


)










=

















d


=


1



















m


i


n


(


n


,


m


)




















σ


(


d


)













t


=


1





































d
















m


i


n


(


n


,


m


)













































μ


(


t


)





















d


t














n













































d


t














m





























考虑枚举



c

=

d

t

c=dt






c




=








d


t





,那么:





=

d

=

1

m

i

n

(

n

,

m

)

σ

(

d

)

t

=

1

m

i

n

(

n

,

m

)

d

μ

(

t

)

n

d

t

m

d

t

=

c

=

1

m

i

n

(

n

,

m

)

n

c

m

c

d

c

μ

(

c

d

)

σ

(

d

)

=\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{t=1}^{\left\lfloor\frac{min(n,m)}{d}\right\rfloor}\mu(t)\left\lfloor\frac{n}{dt}\right\rfloor\left\lfloor\frac{m}{dt}\right\rfloor\\ =\sum_{c=1}^{min(n,m)}\left\lfloor\frac{n}{c}\right\rfloor\left\lfloor\frac{m}{c}\right\rfloor\sum_{d|c}\mu(\frac{c}{d})\sigma(d)






=

















d


=


1



















m


i


n


(


n


,


m


)




















σ


(


d


)













t


=


1





































d
















m


i


n


(


n


,


m


)













































μ


(


t


)





















d


t














n













































d


t














m


































=

















c


=


1



















m


i


n


(


n


,


m


)





































c














n













































c














m





































d





c





























μ


(













d














c




















)


σ


(


d


)





线性筛出



μ

\mu






μ









σ

\sigma






σ





并预处理出它们的dirichlet卷积的前缀和



g

g






g





,然后除法分块处理即可做到



O

(

n

)

O(\sqrt{n})






O


(










n
























)





处理一次询问.

考虑离线处理



a

a






a





的限制.我们先对询问按照



a

a






a





排序,把所有



d

d






d





按照



σ

(

d

)

\sigma(d)






σ


(


d


)





大小排序,并用树状数组动态维护



g

g






g





,即可做到



O

(

n

log

2

n

+

Q

n

log

n

)

O(n\log^2n+Q\sqrt{n}\log n)






O


(


n





lo

g











2











n




+








Q










n


























lo

g





n


)





.

具体来说,每次当我们要加入一个数



d

d






d





的贡献时,我们枚举



d

d






d





的倍数,把这些倍数加上



d

d






d





的贡献.查询时用树状数组维护前缀和即可.

代码如下:

#include<bits/stdc++.h>
  using namespace std;

#define Abigail inline void
typedef long long LL;

const int N=100000,Q=20000;
const LL mod=(1LL<<31)-1;

int tp,pr[N+9],b[N+9];
LL mu[N+9],sigma[N+9],sd[N+9];

void sieve(int n){      //先把约数和函数筛错,重写一遍后再把Mobius函数筛错的我是不是没了...
  for (int i=2;i<=n;++i) b[i]=1;
  sigma[1]=mu[1]=1;int v;
  for (int i=2;i<=n;++i){
  	if (b[i]) pr[++tp]=i,mu[i]=-1,sigma[i]=sd[i]=i+1;
  	for (int j=1;j<=tp&&i*pr[j]<=n;++j){
  	  b[v=i*pr[j]]=0;
  	  if (i%pr[j]==0){
  	  	mu[v]=0;
  	  	sd[v]=sd[i]*pr[j]+1;sigma[v]=sigma[i]/sd[i]*sd[v];
  	    break;
  	  }
  	  mu[v]=-mu[i];
  	  sd[v]=pr[j]+1;sigma[v]=sigma[i]*sigma[pr[j]];
  	}
  }
}

int t;
struct Question{
  int n,m,id;
  LL a;
}q[Q+9];
LL ans[Q+9];

bool cmp1(const Question &a,const Question &b){return a.a<b.a;}

int d[N+9];

bool cmp2(const int &a,const int &b){return sigma[a]<sigma[b];}

LL g[N+9];

void Bit_add(int x,LL v){for (;x<=N;x+=x&-x) g[x]+=v;}
LL Bit_query(int x){LL sum=0;for (;x;x-=x&-x) sum+=g[x];return sum;}
LL Bit_query(int x,int y){return Bit_query(y)-Bit_query(x-1);}

void solve_add(int x){
  for (int i=1;i*x<=N;++i)
    Bit_add(i*x,sigma[x]*mu[i]);
}

LL solve_query(int n,int m){
  LL ans=0;
  if (n>m) swap(n,m);
  for (int l=1,r;l<=n;l=r+1){
  	r=min(n/(n/l),m/(m/l));
  	ans+=(n/l)*(m/l)*Bit_query(l,r);
  }
  return ans;
}

Abigail into(){
  scanf("%d",&t);
  for (int i=1;i<=t;++i){ 
    scanf("%d%d%lld",&q[i].n,&q[i].m,&q[i].a);
    q[i].id=i;
  } 
}

Abigail work(){
  sieve(N);
  sort(q+1,q+1+t,cmp1);
  for (int i=1;i<=N;++i) d[i]=i;
  sort(d+1,d+1+N,cmp2);
  int now=0;
  for (int i=1;i<=t;++i){
  	while (now<N&&sigma[d[now+1]]<=q[i].a) solve_add(d[++now]);
    ans[q[i].id]=solve_query(q[i].n,q[i].m);
  }
}

Abigail outo(){
  for (int i=1;i<=t;++i)
    printf("%lld\n",ans[i]&mod);
}

int main(){
  into();
  work();
  outo();
  return 0;
}



版权声明:本文为hzk_cpp原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。