zoukankan      html  css  js  c++  java
  • hdu6069(简单数学+区间素数筛法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6069

    题意: 给出 l, r, k.求:(lambda d(i^k))mod998244353,其中 l <= i <= r, d(i) 为 i 的因子个数.

    思路:若 x 分解成质因子乘积的形式为 x = p1^a1 * p2^a2 * ... * pn^an,那么 d(x) = (a1 + 1) * (a2 + 1) * ... * (an + 1) .显然 d(x^k) = (a1 * k + 1) * (a2 * k + 1) * ... * (an * k + 1) .

    但如果仅仅以此暴力求解的话是会 tle 的, 需要用下区间素数筛法并且在筛选区间内合数时将其质因分解,将 i 对答案的贡献存储到 sum 数组中,然后再遍历一次统计素数对答案的贡献并将所有贡献累加起来即可.

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define ll long long
     5 using namespace std;
     6 
     7 const int MAXN = 1e6 + 10;
     8 const int mode = 998244353;
     9 int prime[MAXN], tag[MAXN], tot;
    10 ll sum[MAXN], gel[MAXN];
    11 
    12 void get_prime(void){
    13     for(int i = 2; i < MAXN; i++){
    14         if(!tag[i]){
    15             prime[tot++] = i;
    16             for(int j = 2; j * i < MAXN; j++){
    17                 tag[j * i] = 1;
    18             }
    19         }
    20     }
    21 }
    22 
    23 ll Max(ll a, ll b){
    24     return a > b ? a : b;
    25 }
    26 
    27 int main(void){
    28     get_prime();
    29     ll l, r;
    30     int k, t;
    31     scanf("%d", &t);
    32     while(t--){
    33         scanf("%lld%lld%d", &l, &r, &k);
    34         for(int i = 0; i <= r - l; i++){
    35             sum[i] = 1; //sum[i]记录i+l对答案的贡献
    36             gel[i] = i + l; //将所有元素放到a数组里
    37         }
    38         for(int i = 0; i < tot; i++){
    39             ll a = (l + prime[i] - 1) / prime[i] * prime[i];
    40             for(ll j = a; j <= r; j += prime[i]){ // 筛[l, r]内的合数
    41                 ll cnt = 0;
    42                 while(gel[j - l] % prime[i] == 0){
    43                     cnt++;
    44                     gel[j - l] /= prime[i];
    45                 }
    46                 sum[j - l] = sum[j - l] * (cnt * k + 1 % mode);
    47                 if(sum[j - l] >= mode) sum[j - l] %= mode;
    48             }
    49         }
    50         ll sol = 0;
    51         for(int i = 0; i <= r - l; i++){
    52             if(gel[i] != 1) sum[i] = sum[i] * (k + 1);
    53             sol += sum[i];
    54             if(sol >= mode) sol %= mode;
    55         }
    56         printf("%lld
    ", sol);
    57     }
    58     return 0;
    59 }
    View Code
    (i=lrd(ik))mod998244353
    (i=lrd(ik))mod998244353
    (i=lrd(ik))mod998244353
  • 相关阅读:
    关于网站的性能瓶颈——(阅读笔记)
    Servlet原理解析
    配置Ubuntu Server高速aptget源
    字节对齐
    linux学习笔记—之—linux文件管理
    JavaWeb过滤器Filter
    C语言编程程序的内存布局
    修改Linux下MySQL编码
    C语言中——关于typedef
    linux学习笔记—之—LVM管理
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7294176.html
Copyright © 2011-2022 走看看