zoukankan      html  css  js  c++  java
  • 1363 最小公倍数之和

    题目来源: SPOJ
    基准时间限制:1.5 秒 空间限制:131072 KB 
    给出一个n,求1-n这n个数,同n的最小公倍数的和。
    例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66。
    由于结果很大,输出Mod 1000000007的结果。
    Input
    第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 50000)
    第2 - T + 1行:T个数A[i](A[i] <= 10^9)
    Output
    共T行,输出对应的最小公倍数之和
    Input示例
    3
    5
    6
    9
    Output示例
    55
    66
    279
    思路:欧拉函数;
    最小公倍数可以表示为n*m/gcd(n,m);那么要求的就可以写为sum(i,N)= N*sum(i/gcd(N,i));我们把式子再化下就是(N/gcd(N,i))*gcd(N,i)*sum(i/gcd(N,i));
    那么后面i/gcd(N,i)是与N/gcd(N,i)互质的数,那么当那么sum(i/gcd(N,i)),就是oula(N/gcd(N,i))*(N/gcd(N,i))/2;N/gcd(N,i)为N的约数,所以只要求所有N的约数,那么分解N,dfs求约数。
      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<queue>
      6 #include<math.h>
      7 #include<set>
      8 #include<vector>
      9 #include<string.h>
     10 using namespace std;
     11 typedef long long LL;
     12 bool prime[100010];
     13 int ans[100010];
     14 int ak[105];
     15 int cnt[105];
     16 int p;
     17 int fin[100001];
     18 int oula[100010];
     19 const int mod = 1000000007;
     20 void slove(LL n);
     21 void dfs(int n,int m,int c,int r);
     22 int  quick(int n,int m);
     23 int main(void)
     24 {
     25     int T;
     26     LL n;
     27     scanf("%d",&T);
     28     int i,j;
     29     for(i = 2; i < 1000; i++)
     30     {
     31         if(!prime[i])
     32         {
     33             for(j = i; (i*j) <= 100005; j++)
     34             {
     35                 prime[i*j] = true;
     36             }
     37         }
     38     }
     39     int cn = 0;
     40     for(i = 2; i <= 100005 ; i++)
     41     {
     42         if(!prime[i])
     43             ans[cn++] = i;
     44     }
     45     while(T--)
     46     {
     47         scanf("%lld",&n);
     48         slove(n);
     49     }
     50     return 0;
     51 }
     52 void slove(LL n)
     53 {
     54     int f = 0;
     55     int c = 0;
     56     int t = -1;
     57     p = 0;
     58     LL pp = n;
     59     memset(cnt,0,sizeof(cnt));
     60     while(n > 1)
     61     {
     62         while(n%ans[f] == 0)
     63         {
     64             if(c == 0)
     65             {
     66                 c = 1;
     67                 t++;
     68                 ak[t] = ans[f];
     69                 cnt[t]++;
     70             }
     71             else cnt[t]++;
     72             n/=ans[f];
     73         }
     74         c = 0;
     75         f++;
     76         if(ans[f]*ans[f]>n)
     77             break;
     78     }
     79     if(n>1)
     80     {
     81         t++;
     82         ak[t]=n;
     83         cnt[t]++;
     84     }
     85     dfs(0,t+1,1,1);
     86     LL sum = 0;
     87     int i;
     88     for(i = 0; i < p; i++)
     89     {
     90         sum =(sum+((LL)oula[i]*(LL)fin[i]/2)%mod)%mod;
     91     }
     92     printf("%lld
    ",(sum+1)*(LL)pp%mod);
     93 }
     94 void dfs(int n,int m,int c,int r)
     95 {
     96     if(n == m)
     97     {
     98         fin[p] = c;
     99         oula[p++] = r;
    100         return ;
    101     }
    102     int s = 1;
    103     int i;
    104     for(i = 0; i <= cnt[n]; i++)
    105     {
    106         if(s==1)
    107         {
    108             dfs(n+1,m,c*s,r);
    109         }
    110         else
    111         {
    112             dfs(n+1,m,c*s,r*s/ak[n]*(ak[n]-1));
    113         }
    114         s *= ak[n];
    115     }
    116 }
    
    
    油!油!you@
  • 相关阅读:
    Vue脚手架runtime-only中render函数的参数为什么是h?
    Vue中的 key 属性
    TypeScript安装以及使用
    Vue浏览器调试工具VueTools安装以及使用
    VueRouter路由跳转报错:vue-router.esm.js?fe87:2100 Uncaught (in promise) NavigationDuplicated
    VSCode使用webpack指令,因为在此系统上禁止运行脚本。
    尤雨溪在 vue3.0 beta 上推荐的 no webpack 小工具 vite
    celery task异步任务
    Notepad++使用
    Django基础013--redis开发
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5835982.html
Copyright © 2011-2022 走看看