zoukankan      html  css  js  c++  java
  • 【JZOJ3812】【洛谷P2261】余数求和【数论,数学】【规律】

    题目大意:

    题目链接:

    洛谷:https://www.luogu.org/problemnew/show/P2261
    JZOJ:https://jzoj.net/senior/#main/show/3912

    给定x,yx,y,求
    i=1yx%isum^{y}_{i=1}x\%i


    思路:

    首先暴力打个表。

    1- 0
    2- 0 0
    3- 0 1 0
    4- 0 0 1 0
    5- 0 1 2 1 0
    6- 0 0 0 2 1 0
    7- 0 1 1 3 2 1 0
    8- 0 0 2 0 3 2 1 0
    9- 0 1 0 1 4 3 2 1 0
    10- 0 0 1 2 0 4 3 2 1 0
    11- 0 1 2 3 1 5 4 3 2 1 0
    12- 0 0 0 0 2 0 5 4 3 2 1 0
    13- 0 1 1 1 3 1 6 5 4 3 2 1 0
    14- 0 0 2 2 4 2 0 6 5 4 3 2 1 0
    15- 0 1 0 3 0 3 1 7 6 5 4 3 2 1 0
    16- 0 0 1 0 1 4 2 0 7 6 5 4 3 2 1 0
    17- 0 1 2 1 2 5 3 1 8 7 6 5 4 3 2 1 0
    18- 0 0 0 2 3 0 4 2 0 8 7 6 5 4 3 2 1 0
    19- 0 1 1 3 4 1 5 3 1 9 8 7 6 5 4 3 2 1 0
    20- 0 0 2 0 0 2 6 4 2 0 9 8 7 6 5 4 3 2 1 0
    21- 0 1 0 1 1 3 0 5 3 1 10 9 8 7 6 5 4 3 2 1 0
    22- 0 0 1 2 2 4 1 6 4 2 0 10 9 8 7 6 5 4 3 2 1 0
    23- 0 1 2 3 3 5 2 7 5 3 1 11 10 9 8 7 6 5 4 3 2 1 0
    24- 0 0 0 0 4 0 3 0 6 4 2 0 11 10 9 8 7 6 5 4 3 2 1 0
    25- 0 1 1 1 0 1 4 1 7 5 3 1 12 11 10 9 8 7 6 5 4 3 2 1 0
    26- 0 0 2 2 1 2 5 2 8 6 4 2 0 12 11 10 9 8 7 6 5 4 3 2 1 0
    27- 0 1 0 3 2 3 6 3 0 7 5 3 1 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    28- 0 0 1 0 3 4 0 4 1 8 6 4 2 0 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    29- 0 1 2 1 4 5 1 5 2 9 7 5 3 1 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    30- 0 0 0 2 0 0 2 6 3 0 8 6 4 2 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

    ii行的第jj个数字表示x=i,y=jx=i,y=j时的答案。(第一列是行标号)。
    然后就会发现:
    l=[x÷i],r=[x÷(i+1)]l=[xdiv i],r=[xdiv (i+1)]时,lrlsim r之间的所有数字被xx除之后的余数是一个公差为ii的等比数列。([][]表示向下取整)
    那么可以枚举ii,求出l,rl,r,然后求出项数,最后用等差数列求和公式即可。
    但是当x=y=109x=y=10^9时,需要枚举10910^9次,会稳稳超时。
    所以当[x÷i]=[x÷(i+1)][xdiv i]=[xdiv (i+1)]时,剩余的数字在nsqrt{n}左右,直接推出枚举暴力求解即可。
    然后就愉快的拿到8080分。
    注意题目没说yxyleq x,所以当y>xy>x时,直接

    if (m>n)
    {
    	ans+=(m-n)*n;
    	m=n;
    }
    

    时间复杂度:O(O(玄学)),大约O(x)O(sqrt{x})吧。


    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    ll n,m,ans,a1,an,s,k;
    
    int main()
    {
    	cin>>n>>m;
    	if (m>n)
    	{
    		ans+=(m-n)*n;
    		m=n;
    	}
    	for (ll i=n/m;(n/i)!=(n/(i+1));i++)  //枚举i,判断[x/i]和[x/(i+1)]
    	{
    		a1=n%min(n/i,m);  //首项
    		an=n%(n/(i+1)+1);  //末项
    		ans+=(a1+an)*(an-a1+i)/i/2;  //求和公式
    		k=n/(i+1)+1;  //记录计算到那个位置
    	}
    	for (ll i=1;i<k;i++)  //剩余暴力求解
    		ans+=n%i;
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    12.12 怀北滑雪场滑雪记
    datetime类型offset-aware与offset-navie
    Django-models中的choise
    什么是__name__()
    单机Ubuntu安装第二个Mysql服务
    Ubuntu下的Python安装
    设置mysql允许外网访问
    Ubuntu初次设置root密码
    使用VMware+Ubuntu,无法切换大小写的异常处理
    XShell/Xftp 无法连接 Ubuntu20
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998367.html
Copyright © 2011-2022 走看看