zoukankan      html  css  js  c++  java
  • 【bzoj3529】数表

    Description

    给定n,m,a(n,m<=107,a<=109),求$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}f(gcd(i,j))[f(gcd(i,j))<=a]$(多组数据,q<=200000),其中,f(n)表示n的约数和。


    Solution

    我们忽略$f(gcd(i,j))<=a$,可得

    $ans=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}f(gcd(i,j))$

    $=\sum\limits_{d=1}^{n}f(d)\sum\limits_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum\limits_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[gcd(i,j)=1]$

    $=\sum\limits_{d=1}^{n}f(d)\sum\limits_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum\limits_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}\sum\limits_{p|i,p|j}μ(p)$

    $=\sum\limits_{d=1}^{n}f(d)\sum\limits_{p=1}^{\left\lfloor\frac{n}{d}\right\rfloor}μ(p)\left\lfloor\frac{n}{pd}\right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor$

    记$t=pd$,则

    $ans=\sum\limits_{t=1}^{n}\left\lfloor\frac{n}{t}\right\rfloor\left\lfloor\frac{m}{t}\right\rfloor\sum\limits_{d|t}f(d)μ(\frac{t}{d})$

    现在看$f(gcd(i,j))<=a$这一限制条件,我们用线性筛预处理出$\sum\limits_{d|t}f(d)μ(\frac{t}{d})$的前缀和后,离线处理询问,将询问按a的大小从小往大排,每次处理询问将符合条件的f值加入树状数组,然后按照$\left\lfloor\frac{n}{t}\right\rfloor$的值分块处理就可以啦,时间复杂度$O(q\sqrt{n})$。

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100000;
     6 const int Q=20000;
     7 struct node{
     8     int val,id;
     9 }a[N+10]={0};
    10 struct ques{
    11     int n,m,a,id;
    12 }f[Q+10]={0};
    13 int q,p[N+10]={0},miu[N+10]={0},t[N+10]={0},s[N+10]={0};
    14 int ans[Q+10]={0};
    15 bool check[N+10]={false};
    16 bool cmp1(node a,node b){
    17     return a.val<b.val;
    18 }
    19 bool cmp2(ques a,ques b){
    20     return a.a<b.a;
    21 }
    22 void get_miu(){
    23     miu[1]=a[1].val=1;
    24     for(int i=2;i<=N;i++){
    25         if(!check[i]){
    26             miu[p[++p[0]]=i]=-1;
    27             a[i].val=t[i]=i+1;
    28         }
    29         for(int j=1;i*p[j]<=N&&j<=p[0];j++){
    30             check[i*p[j]]=true;
    31             if(i%p[j]){
    32                 miu[i*p[j]]=-miu[i];
    33                 t[i*p[j]]=p[j]+1;
    34                 a[i*p[j]].val=a[i].val*t[i*p[j]];
    35             }
    36             else{
    37                 t[i*p[j]]=t[i]*p[j]+1;
    38                 a[i*p[j]].val=a[i].val/t[i]*t[i*p[j]];
    39                 break;
    40             }
    41         }
    42     }
    43     for(int i=1;i<=N;i++)
    44         a[i].id=i;
    45     sort(a+1,a+N+1,cmp1);
    46     return;
    47 }
    48 void update(int x,int k){
    49     for(;x<=N;x+=x&-x)
    50         s[x]+=k;
    51     return;
    52 }
    53 int query(int x){
    54     int ret=0;
    55     for(;x;x-=x&-x)
    56         ret+=s[x];
    57     return ret;
    58 }
    59 int solve(int n,int m){
    60     int ret=0;
    61     if(n>m)
    62         swap(n,m);
    63     for(int i=1,j;i<=n;i=j+1)
    64         ret+=(query(j=min(n/(n/i),m/(m/i)))-query(i-1))*(n/i)*(m/i);
    65     return ret&0x7fffffff;
    66 }
    67 int main(){
    68     get_miu();
    69     scanf("%d",&q);
    70     for(int i=1;i<=q;i++){
    71         scanf("%d%d%d",&f[i].n,&f[i].m,&f[i].a);
    72         f[i].id=i;
    73     }
    74     sort(f+1,f+q+1,cmp2);
    75     a[N+1].val=0x3f3f3f3f;
    76     for(int i=1,j=1;i<=q;i++){
    77         for(;a[j].val<=f[i].a;j++)
    78             for(int k=a[j].id;k<=N;k+=a[j].id)
    79                 update(k,a[j].val*miu[k/a[j].id]);
    80         ans[f[i].id]=solve(f[i].n,f[i].m);
    81     }
    82     for(int i=1;i<=q;i++)
    83         printf("%d\n",ans[i]);
    84     return 0;
    85 }
  • 相关阅读:
    stompjs使用
    WKWebView新窗口打开链接
    iOS实现自定义拍照页面
    Universal Link
    社群app开发问题记录
    C#中try catch finally
    如何生成代码项目的工程结构
    C# SqlSugar基于 .NET 开源ORM框架
    C# DataGridView 行和列的操作
    禁止EditText 自动弹出软键盘
  • 原文地址:https://www.cnblogs.com/gzez181027/p/bzoj3529.html
Copyright © 2011-2022 走看看