zoukankan      html  css  js  c++  java
  • luoguP3935计算

    容易发现,(f(x))等于因子数量。

    对于(l,r)都很大的题目,一般可以采用前缀和的方式解决。

    (sum(x)=sum_{i=1}^{i<=x} f(i))

    考虑枚举因数。

    如果一个因数为(v),那么在(1->x)的范围内,(v)出现了(lfloor x/v floor)次.

    于是我们可以这样子表示(sum(x)):

    [ sum(x)=sum_{i=1}^{i<=x} lfloor x/i floor ]

    观察一下规律:

    比如我们要求(sum(14)),那么求解过程如下:

    [ 14/1=14\ 14/2=7\ 14/3=4\ 14/4=3\ 14/5=2\ 14/6=2\ 14/7=2\ 14/8=1\ 14/9=1\ 14/10=1\ 14/11=1\ 14/12=1\ 14/13=1\ 14/14=1\ ]

    发现有很多重复的,比如:

    [14/5=2\ 14/6=2\ 14/7=2\ ]

    于是我们可以把它划分成若干个重复的序列进行求解


    我们把重复的左边设作(l),(这里的(l=5))

    我们把重复的右边设作(r),(这里的(r=7))

    发现一个性质:

    [ lfloor v/l floor=lfloor v/r floor ]

    如果我们知道了(l),那么L

    [ r=v/lfloor v/l floor\ ]

    上面的式子可以举例子感性理解得出

    当然,你也可以二分求解这个(r)((O(log_2(n)))


    我们知道了(l,r)之后,那么对(sum(x))的贡献就是(lfloor x/l floor imes(r-l+1))

    关于时间复杂度:
    如果你知道,请告诉我

    不过根据跑出来的时间我猜(sqrt{n})级别的

    类似题目:余数求和

    记得:取模取模取模取模取模取模


    代码

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<map>
    #include<queue>
    #include<iostream>
    #include<cmath>
    #define int long long   
    using namespace std;
    inline int gi(){char tmp=getchar();int flag=1;while(tmp<'0'||tmp>'9'){if(tmp=='-'){flag=-1;tmp=getchar();break;}tmp=getchar();}int ans=0;while(tmp<='9' and tmp>='0') {ans=ans*10+tmp-'0';tmp=getchar();}return ans*flag;}
    inline void write(int x){static int stk[100], top = 0;if (x == 0) { putchar('0'); putchar(' ');return; }if (x < 0) { x = -x; putchar('-'); }while (x) { stk[++top] = x % 10; x /= 10; }while (top) { putchar(stk[top--] + '0'); }putchar(' ');}
    #define line() putchar('
    ');
    #define Mem(Arr,V) memset(Arr,V,sizeof Arr);
    #define Mcpy(Arr,qwq) memcpy(Arr,qwq,sizeof qwq);
    #define max3(a,b,c) max(max(a,b),c)
    #define max4(a,b,c,d) max4(max3(a,b,c),d);
    #define in(a) a=gi()
    #define in2(a,b) in(a),in(b)
    #define in3(a,b,c) in2(a,b),in(c)
    #define in4(a,b,c,d) in3(a,b,c),in(d)
    #define write2(a,b) write(a),write(b)
    #define write3(a,b,c) write2(a,b),write(c)
    #define write4(a,b,c,d) write3(a,b,c),write(d)
    const int mod=998244353;
    inline void smin(int &x,int y){x=min(x,y);}
    inline void smax(int &x,int y){x=max(x,y);}
    inline int Mul(int x,int y)
    {
    	int ans=0;
    	while(y)
    	{
    		if(y&1) ans+=x;
    		x=x+x;
    		x%=mod;
    		ans%=mod;
    		y>>=1;
    	}
    	if(ans<=0)
    	{
    		write2(x,y);
    		exit(0);
    	}
    	return ans;
    }
    inline int Sum(int v)
    {
    	if(v==0) return 0;
    	int ans=0;
    	for(int l=1,r;l<=v;l=r+1)
    	{
    		r=v/(v/l);
    		ans+=((r-l+1)%mod*((v/l)%mod));
    		ans%=mod;
    		if(ans<=0)
    		{
    			// write2(x,y);
    			exit(0);
    		}
    		l=r+1;
    	}
    	return ans%mod;
    }
    signed main()
    {
    	#ifndef ONLINE_JUDGE
    		freopen("data.in","r",stdin);
    	#endif
    	int l,r;
    	in2(l,r);
    	// write(Mul(l,r));
    	// return 0;
    	write(((Sum(r)-Sum(l-1)%mod)+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    C#使用枚举方法来实现读取用户电脑中安装的软件
    C#实现窗体阴影效果
    [转]SQLserver字符串分割函数
    [转]WinForm实现win7 Aero磨砂效果介绍
    C#通过鼠标点击panel移动来控制无边框窗体移动
    [转]Table交替行变色 鼠标经过变色 单击变色
    《面向对象程序设计》 三 Calculator 计算器初步
    PAT 1001A+B Format
    大一下学期的自我目标
    《面向对象程序设计》第二次作业
  • 原文地址:https://www.cnblogs.com/guodongLovesOi/p/11617001.html
Copyright © 2011-2022 走看看