P3312 [SDOI2014]数表

[SDOI2014]数表

题意即求:

\[\sum _ { i = 1 } ^ { n } \sum _ { j = 1 } ^ { m } \left[ \sigma _ 1 ( \gcd ( i , j )) \le a \right] \sigma _ 1 ( \gcd ( i , j ) ) \pmod { 2 ^ {31}} \]

其中 \(T\le 2 \times 10 ^4\)\(n , m \le 10 ^ 5\)

直接推导:

\[\begin{aligned} & \sum _ { i = 1 } ^ { n } \sum _ { j = 1 } ^ { m } \left[ \sigma _ 1 ( \gcd ( i , j )) \le a\right] \sigma _ 1 ( \gcd ( i , j ) ) \\ = & \sum _ { d = 1 } \sum _ { i = 1 } ^ { n } \sum _ { j = 1 } ^ { m } \left[ \sigma _ 1 ( d ) \le a \right] \left[ \gcd ( i , j ) = d \right] \sigma _ 1 ( d ) \\ = & \sum _ { d = 1 } \left[ \sigma _ 1 ( d ) \le a \right] \sigma _ 1 ( d ) \sum _ { i = 1 } ^ { \left\lfloor n / d \right\rfloor } \sum _ { j = 1 } ^ { \left\lfloor m / d \right\rfloor } \left[ \gcd ( i , j ) = 1 \right] \\ = & \sum _ { d = 1 } \left[ \sigma _ 1 ( d ) \le a \right] \sigma _ 1 ( d ) \sum _ { i = 1 } ^ { \left\lfloor n / d \right\rfloor } \sum _ { j = 1 } ^ { \left\lfloor m / d \right\rfloor } \sum _ { k \mid i, k\mid j} \mu ( k ) \\ = & \sum _ { d = 1 } \left[ \sigma _ 1 ( d ) \le a \right] \sigma _ 1 ( d ) \sum _ { k =1} \mu ( k ) \left\lfloor \dfrac{ n }{ k d } \right\rfloor \left\lfloor \dfrac{ m }{ k d } \right\rfloor \\ = & \sum _ {T = 1} \left( \sum _ { d \mid T } \left[ \sigma _ 1 ( d ) \le a \right] \sigma _ 1 ( d ) \mu \left( \dfrac{T}{d} \right) \right) \left\lfloor \dfrac{ n }{ T } \right\rfloor \left\lfloor \dfrac{ m }{ T } \right\rfloor \end{aligned} \]

如果处理好括号内的函数的前缀和求取,我们就可以使用整除分块了。

好像有点难搞。

智商不够,DS 来凑。

离线处理这个题,先把输入数据按 \(a\) 的大小排序。

预处理的时候把 \(\sigma _ 1 (d)\) 的每个点的值放入一个小根堆中。

每次求取一个输入数据的答案时,先从小根堆中取出不超过 \(a\) 的点,按照一般的方法点值修改树状数组即可。

最后的时间复杂度就是 \(O( n \ln ^ 2 n + T \sqrt{n} \ln n )\)

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
namespace Ehnaev{
  inline ll read() {
    ll ret=0,f=1;char ch=getchar();
    while(ch<48||ch>57) {if(ch==45) f=-f;ch=getchar();}
    while(ch>=48&&ch<=57) {ret=(ret<<3)+(ret<<1)+ch-48;ch=getchar();}
    return ret*f;
  }
  inline void write(ll x) {
    static char buf[22];static ll len=-1;
    if(x>=0) {do{buf[++len]=x%10+48;x/=10;}while(x);}
    else {putchar(10);do{buf[++len]=-(x%10)+48;x/=10;}while(x);}
    while(len>=0) putchar(buf[len--]);
  }
}using Ehnaev::read;using Ehnaev::write;
inline void writeln(ll x) {write(x);putchar(10);}

const ll mo=(1ll<<31),N=1e5,M=2e4;

ll T,cnt;
ll mu[N+5],prime[N+5],sgm1[N+5],c[N+5];
bool ff[N+5];

struct Qry{
  ll n,m,a,id,ans;
}a[M+5];

struct node{
  ll val,id;
  inline bool operator > (const node& rhs) const {
    return val>rhs.val;
  }
}t;

priority_queue<node,vector<node>,greater<node> > q;

inline bool cmp1(Qry x,Qry y) {return x.a<y.a;}
inline bool cmp2(Qry x,Qry y) {return x.id<y.id;}

inline void Init() {
  for(ll i=1;i<=N;i++) {
    for(ll j=i;j<=N;j+=i) {
      sgm1[j]=(sgm1[j]+i)%mo;
    }
  }
  for(ll i=1;i<=N;i++) {t.val=sgm1[i];t.id=i;q.push(t);}
  ff[1]=1;mu[1]=1;
  for(ll i=2;i<=N;i++) {
    if(!ff[i]) {prime[++cnt]=i;mu[i]=mo-1;}
    for(ll j=1;j<=cnt&&i*prime[j]<=N;j++) {
      ff[i*prime[j]]=1;
      if(i%prime[j]==0) {
        mu[i*prime[j]]=0;break;
      }
      mu[i*prime[j]]=mu[i]*mu[prime[j]]%mo;
    }
  }
}

inline void Add(ll x,ll y) {for(;x<=N;x+=x&-x) c[x]=(c[x]+y)%mo;}
inline ll Ask(ll x) {ll r=0;for(;x;x-=x&-x) r=(r+c[x])%mo;return r;}

inline void Init_(ll r) {
  while(!q.empty()&&q.top().val<=r) {
    ll ti=q.top().id,tv=q.top().val;
    for(ll i=ti,cn=1;i<=N;i+=ti,cn++) {
      ll tmp=tv*mu[cn]%mo;if(tmp) Add(i,tmp);
    }
    q.pop();
  }
}

int main() {

  T=read();

  for(ll i=1;i<=T;i++) {
    a[i].n=read();a[i].m=read();a[i].a=read();a[i].id=i;
  }
  sort(a+1,a+T+1,cmp1);
  Init();

  for(ll ii=1;ii<=T;ii++) {
    Init_(a[ii].a);
    ll n=a[ii].n,m=a[ii].m;if(n<m) swap(n,m);
    for(ll i=1,j;i<=m;i=j+1) {
      j=min(n/(n/i),m/(m/i));
      ll tmp=(((Ask(j)-Ask(i-1)+mo)%mo)*(n/i)%mo)*(m/i)%mo;
      a[ii].ans=(a[ii].ans+tmp)%mo;
    }
    
  }

  sort(a+1,a+T+1,cmp2);

  for(ll i=1;i<=T;i++) {writeln(a[i].ans);}

  return 0;
}
posted @ 2023-02-06 19:57  Aryper  阅读(15)  评论(0编辑  收藏  举报