zoukankan      html  css  js  c++  java
  • bzoj 2820 YY的GCD

    Description

    神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对kAc这种
    傻×必然不会了,于是向你来请教……多组输入

    Input

    第一行一个整数T 表述数据组数接下来T行,每行两个正整数,表示N, M

    Output

    T行,每行一个整数表示第i组数据的结果

    Sample Input

    2
    10 10
    100 100

    Sample Output

    30
    2791

    HINT

    T = 10000

    N, M <= 10000000


      题目大意 (题目太简洁不需要大意)。

      根据常用套路,我们有

      

      显然TLE,为了更好的分段计算,所以考虑把后面两个向下取整取整的分数挪出来。于是得到了下面这个优美的式子:

      现在就来考虑后面那个求和。

      考虑莫比乌斯函数的性质和p为质数。

      1)当T存在一个质因子的指数超过2,显然对答案贡献为0

      2)当T存在超过1个质因子的指数为2,显然对答案贡献为0

      3)当T只存在1个质因子的指数为2,那么当且仅当p的值为这个质因子时,对答案才有贡献,这个贡献为-1的不同质因子次幂。

      4)当T的质因子的指数均为1,那么对答案的贡献为T的质因子个数乘-1的不同质因子个数减一 次幂。

      显然可以用线性筛预处理出这个的值的前缀和,这样就可以做到单次查询根号级别。

      至于如何用线性筛预处理,我记录了一个enable表示是否存在1个质因子的指数大于等于2和defp表示不同的质因子的个数。详细的过程请看代码。

    Code

     1 /**
     2  * bzoj
     3  * Problem#2820
     4  * Accepted
     5  * Time:4708ms
     6  * Memory:141912k
     7  */
     8 #include <bits/stdc++.h>
     9 #ifndef WIN32
    10 #define Auto "%lld"
    11 #else
    12 #define Auto "%I64d"
    13 #endif
    14 using namespace std;
    15 typedef bool boolean;
    16 
    17 #define LL long long
    18 
    19 const int limit = 1e7;
    20 
    21 int num = 0;
    22 int prime[1000000];
    23 boolean vis[limit + 1];
    24 boolean enable[limit + 1];
    25 LL g[limit + 1];
    26 int defp[limit + 1];
    27 inline void Euler() {
    28     memset(vis, false, sizeof(vis));
    29     memset(enable, true, sizeof(enable));
    30     g[0] = g[1] = 0;
    31     for(int i = 2; i <= limit; i++) {
    32         if(!vis[i])    prime[num++] = i, g[i] = 1, defp[i] = 1;
    33         for(int j = 0; j < num && i * 1LL * prime[j] <= limit; j++) {
    34             int c = i * prime[j];
    35             vis[c] = true;
    36             if(i % prime[j]) {
    37                 defp[c] = defp[i] + 1;
    38                 enable[c] = enable[i];
    39                 g[c] = (enable[i]) ? ((defp[c]) * ((defp[c] & 1) ? (1) : (-1))) : (-g[i]);
    40             } else {
    41                 defp[c] = defp[i];
    42                 enable[c] = false;
    43                 g[c] = (enable[i]) ? ((defp[c] & 1) ? (-1) : (1)) : (0);
    44                 break;
    45             }
    46         }
    47     }
    48     for(int i = 2; i <= limit; i++)
    49         g[i] += g[i - 1];
    50 //    cout << num << endl;
    51 //    for(int i = 1; i <= 20; i++)
    52 //        cout << i << " " << g[i] << " " << defp[i] << endl;
    53 }
    54 
    55 int n, m;
    56 inline void init() {
    57     scanf("%d%d", &n, &m);
    58 }
    59 
    60 inline void solve() {
    61     if(n > m)    swap(n, m);
    62     LL res = 0;
    63     for(int i = 1, j; i <= n; i = j + 1) {
    64         j = min(n / (n / i), m / (m / i));
    65         res += (n / j) * 1LL * (m / j) * (g[j] - g[i - 1]); 
    66     }
    67     printf(Auto"
    ", res);
    68 }
    69 
    70 int T;
    71 int main() {
    72     Euler();
    73     scanf("%d", &T);
    74     while(T--) {
    75         init();
    76         solve();
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    nginx 指令之 try_files
    java tomcat jvm优化
    使用phpexcel上传下载excel文件
    路由器数据统计SQL脚本
    微信公众平台开发(122) 获取微信会员卡用户姓名和手机号
    微信会员卡积分规则
    IP白名单
    关于公众平台接口不再支持HTTP方式调用的公告
    微信公众号特异功能列表
    微信小程序 TOP100 榜单
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7248771.html
Copyright © 2011-2022 走看看