比较好的题目 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;
}