zoukankan      html  css  js  c++  java
  • [BZOJ2693]jzptab

    【题目描述】

    为了研究最小公倍数,他画了一张N*M的表格。每个格子里写了一个数字,其中的i行的j列写着数lcm(i,j)。crash表格里所有数的和mod100000009的值。

    【输入格式】

    第一行输入T,表示数据组数。接下来的T行,每行输入N和M

    【输出格式】

    对于每个询问,输出表格中所有数的和mod100000009的值

    【样例输入】

    1
    4 5
    

    【样例输出】

    122

    【提示】

    T<=10000;N,M<=10000000

    先附一个链接:

    https://www.cnblogs.com/yoyoball/p/8231397.html

    我是直接枚举i和i的倍数j计算f()的,可以证明这样只有O(nlogn)

    但是链接中运用积性函数性质用线性筛更好

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long lol;
     8 int Q[10001][2],Mod=100000009,inv2,N,tot,n,m;
     9 int f[10000005],ans,mu[10000005],prime[5000005];
    10 bool vis[10000005];
    11 int get_sum(int x,int y)
    12 {
    13   int s1,s2;
    14   s1=(1ll*(1+x)*x/2)%Mod;
    15   s2=(1ll*(1+y)*y/2)%Mod;
    16   return 1ll*s1*s2%Mod;
    17 }
    18 void pre()
    19 {int i,j;
    20   mu[1]=1;
    21   for (i=2;i<=N;i++)
    22     {
    23       if (vis[i]==0)
    24     {
    25       ++tot;
    26       prime[tot]=i;
    27       mu[i]=-1;
    28     }
    29       for (j=1;j<=tot;j++)
    30     {
    31       if (1ll*i*prime[j]>N) break;
    32       vis[i*prime[j]]=1;
    33       if (i%prime[j]==0)
    34         {
    35           mu[i*prime[j]]=0;
    36           break;
    37         }
    38       else mu[i*prime[j]]=-mu[i];
    39     }
    40     }
    41   for (i=1;i<=N;i++)
    42     {
    43       for (j=1;j<=N;j++)
    44     {
    45       if (1ll*i*j>N) break;
    46       f[i*j]+=i*mu[i];
    47       f[i]=(f[i]+Mod)%Mod;
    48     }
    49     }
    50   for (i=1;i<=N;i++)
    51     f[i]=(1ll*f[i]*i%Mod+f[i-1])%Mod;
    52 }
    53 int main()
    54 {
    55   int T,i,j,pos;
    56   cin>>T;
    57   for (i=1;i<=T;i++)
    58     {
    59       scanf("%d%d",&Q[i][0],&Q[i][1]);
    60       if (Q[i][0]>Q[i][1]) swap(Q[i][0],Q[i][1]);
    61       N=max(N,Q[i][0]);
    62     }
    63   pre();
    64   for (j=1;j<=T;j++)
    65     {
    66       ans=0;
    67       n=Q[j][0],m=Q[j][1];
    68       for (i=1;i<=n;i=pos+1)
    69     {
    70       pos=min(n/(n/i),m/(m/i));
    71       ans=(ans+1ll*get_sum(n/i,m/i)*((f[pos]-f[i-1]+Mod)%Mod)%Mod)%Mod;
    72     }
    73       printf("%d
    ",ans);
    74     }
    75 }
  • 相关阅读:
    c#基础之集合
    找出子字符串在字符串中的所有索引
    c# 排序
    C#基础之枚举
    验证用户名不为空并且不存在
    验证用户名和密码,输入三次不正确就锁定账号
    c#基础
    linux使用
    python之logging模块
    手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8340826.html
Copyright © 2011-2022 走看看