jdfz “核”系列 2782~2786

比较好的题目 by ygy学长 感兴趣的可以来做一做。

题目描述

2782: 和之和

Description

给出数n,求ans=(n+1)+(n+2)+...+(n+n)

Input

一行,一个整数n

Output

一行,一个整数ans%23333333333333333(2后面16个3)

HINT

0<=n<=1012

题目分析:

一个裸的快速幂 由等差数列通项公式得

 因为向下取整的原因,要讨论一下n的奇偶性

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;    
long long tmp=23333333333333333ll;
long long ans;
long long add(long long x,long long y,long long r)
{
    if(y==0) return 0;
    if(y==1) return x;
    long long t=0;
    while(y)
    {
        if(y&1) t=(t+x)%r;
        x<<=1; x=x%r;
        y>>=1;
    }
    return t;
}
int main()
{
    long long n;
    scanf("%lld",&n);
    if(n%2==0)
        ans=add(n>>1,3*n+1,tmp);
    else
        ans=add(n,(3*n+1)>>1,tmp);
    printf("%lld",ans%tmp);
}

2783: 差之和

Description

给出数n,求ans=(n-1)+(n-2)+...+(n-n)

Input

一行,一个整数n

Output

一行,一个整数ans%23333333333333333(2后面16个3)

HINT

0<=n<=1012

题目分析:

同上题 方式有很多

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;    
long long tmp=23333333333333333;
long long ans;
long long add(long long x,long long y,long long r)
{
    if(y==0) return 0;
    if(y==1) return 0;
    long long t=0;
    while(y)
    {
        if(y&1)
            t=(t+x)%r;
        x<<=1;
        x=x%r;
        y>>=1;
    }
    return t%r;
}
int main()
{
    long long n;
    scanf("%lld",&n);
    ans=add(n,n,tmp);
    if(n&1) ans=ans-add(n,(n+1)/2,tmp);
    else ans=ans-add(n/2,n+1,tmp);
    if(ans<0) ans=(tmp+ans)%tmp;
    printf("%lld",ans);
}

2784: 积之和

Description

给出数n,求ans=(n*1)+(n*2)+...+(n*n)

Input

一行,一个整数n

Output

一行,一个整数ans%23333333333333333(2后面16个3)

HINT

0<=n<=1012

题目分析:

也是同样的题 方法有很多

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;    
long long tmp=23333333333333333;
long long ans;
long long add(long long x,long long y,long long r)
{
    if(y==0) return 0;
    if(y==1) return x;
    long long t=0;
    while(y)
    {
        if(y&1) t=(t+x)%r;
        x<<=1;
        x=x%r;
        y>>=1;
    }
    return t%r;
}
int main()
{
    long long n;
    scanf("%lld",&n);
    if(n&1) ans=add(add(n,(n+1)/2,tmp),n,tmp);
    else ans=add(add(n/2,n+1,tmp),n,tmp);
    printf("%lld",ans%tmp);
}

2785: 商之和

Description

给出数n,求ans=(n/1)+(n/2)+...+(n/n)

Input

一行,一个整数n

Output

一行,一个整数ans%23333333333333333(2后面16个3)

HINT

0<=n<=1012

题目分析:

这道题才是重点

首先 我们要介绍一个特殊的性质:

对于 (i~n/⌊n/i⌋)  ⌊n/i⌋的值是相等的 把原数列分块 我们就可以用快速幂求出值

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
long long n;
long long ans;
long long mod=23333333333333333;
long long ksj(long long x,long long y)
{
    long long sum=0;
    while(y)
    {
        if(y&1) sum=(sum+x)%mod;
        x=(x<<1)%mod;
        y>>=1;
    }
    return sum;
}
int main()
{
    scanf("%lld",&n);
    for(long long i=1;i<=n;)
    {
        long long tmp=n/i;
        long long nmp=n/tmp;
        ans+=ksj(tmp,nmp-i+1);
        i=nmp+1;
        ans%=mod;
    }
    printf("%lld",ans);
    return 0;
}

2786: 余之和

Description

给出数n,求ans=(n%1)+(n%2)+...+(n%n)

Input

一行,一个整数n

Output

一行,一个整数ans%23333333333333333(2后面16个3)

HINT

0<=n<=1012

题目分析:

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
long long n;
long long ans;
long long mod=23333333333333333;
long long ksj(long long x,long long y)
{
    long long sum=0;
    while(y)
    {
        if(y&1) sum=(sum+x)%mod;
        x=(x<<1)%mod;
        y>>=1;
    }
    return sum;
}
long long ksc(long long x,long long y)
{
    long long sum=1;
    while(y)
    {
        if(y&1) sum=ksj(sum,x)%mod;
        x=ksj(x,x)%mod;
        y>>=1;
    }
    return sum;
}
long long calc(long long x,long long nmp)
{
    long long y=nmp-x+1;
    if(y%2==0)
        return ksj(x+nmp,y/2);
    else return ksj((x+nmp)/2,y);
}
long long work(long long tmp,long long nmp,long long x)
{
    long long sum=ksj(n,nmp-x+1);
    sum=(sum-tmp*calc(x,nmp)+mod)%mod;
    return sum%mod;
}
int main()
{
    scanf("%lld",&n);
    for(long long i=1;i<=n;)
    {
        long long tmp=n/i;
        long long nmp=n/tmp;
        ans+=work(tmp,nmp,i);
        ans%=mod;
        i=nmp+1;
    }
    printf("%lld",ans%mod);
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注