zoukankan      html  css  js  c++  java
  • [洛谷P4900]食堂

    题目大意:$n(nleqslant10^6)$组询问,每组询问给出$l,r(l,rleqslant10^6)$,求(${dfrac ij}$表示$dfrac ij$的小数部分):

    $$
    sumlimits_{i=l}^rsumlimits_{j=1}^i{dfrac ij}pmod{998244353}
    $$

    题解:令$f(x)=sumlimits_{i=1}^x{dfrac xi}$
    $$
    f(x+1)=sumlimits_{i=1}^{x+1}{dfrac{x+1}i}\
    f(x+1)=sumlimits_{i=1}^{x+1}{dfrac xi+dfrac 1i}\
    ecause {dfrac{x+1}{x+1}}=0\
    herefore f(x+1)=f(x)+sumlimits_{i=1}^{x}{dfrac 1i}-sumlimits_{i=1}^{x+1}[{dfrac{x+1}i}=0]+1\
    令s_0(x)为x的约数个数\
    即f(x+1)=f(x)+sumlimits_{i=1}^{x}{dfrac 1i}-s_0(x+1)+1
    $$
    求几次前缀和即可

    卡点:

    C++ Code:

    #include <cstdio>
    #include <iostream>
    #define maxn 1000005
    const int mod = 998244353;
    inline void reduce(int &x) { x += x >> 31 & mod; }
    inline int getreduce(int x) { return x + (x >> 31 & mod); }
    
    int n;
    int inv[maxn], sinv[maxn], f[maxn];
    int ans[maxn], sans[maxn];
    int main() {
    	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
    	inv[1] = sinv[1] = 1;
    	for (int i = 2; i < maxn; ++i) {
    		inv[i] = static_cast<long long> (mod - mod / i) * inv[mod % i] % mod;
    		reduce(sinv[i] = sinv[i - 1] + inv[i] - mod);
    	}
    	for (int i = 2; i < maxn; ++i)
    		for (int j = i; j < maxn; j += i) ++f[j];
    	for (int i = 2; i < maxn; ++i) {
    		reduce(ans[i] = ans[i - 1] + sinv[i - 1] - mod);
    		reduce(ans[i] -= f[i]);
    		reduce(sans[i] = sans[i - 1] + ans[i] - mod);
    	}
    	std::cin >> n;
    	while (n --> 0) {
    		static int l, r;
    		std::cin >> l >> r;
    		std::cout << getreduce(sans[r] - sans[l - 1]) << '
    ';
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    0603 学术诚信与道德
    0601 新的冲刺
    0525 Scrum 项目7.0
    0523 Scrum 项目6.0
    0518 Scrum项目5.0
    0512 Scrum 4.0
    0512 操作系统之进程调度
    0511 backlog
    0506 Scrum 项目1.0
    复利计算再升级
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10347165.html
Copyright © 2011-2022 走看看