洛谷P7893
Solution
根据题意,我们可以推出公式
$\sum\limits_{i=1}kn×(-p)i $
这里的 \(k\) 是使得 \(\frac{n}{(-p)^i}=1\) 的最大 \(i\) 值
这里就不给出详细的证明了,可以参考其他大佬的。
根据此公式,我们可以写出简易代码,如下:
signed main()
{
t=read();
while(t--)
{
k=1000;//首先初始化成一个大值,含义继续往下看
ans=0;
i=0;
n=read(),m=read();
if(m==1)//如果是1直接输出0
{
printf("0\n");
continue;
}
while(abs(k)>1)//i是基数时k就是负的,所以这里用绝对值
{
k=n/pow(-m,i);
ans+=k;
i++;
}
printf("%lld\n",ans);
}
return 0;
}
解释一下(大佬可以直接跳过):
-
\(k\) 初始为 \(1000\) 就为了进入while循环
-
\(k\) 是每一步 \(n×(-p)^i\) 的值,\(k\) 随 \(i\) 的改变而改变。
关于while循环条件:
大家可以想一下当 \(n×(-p)^i<1\) 时,后面的 \(k\) 值都为 \(0\) ,对 ans 没有贡献所以不需要再算了。
但是这份代码是过不了的
最后一组数据会超时,因为 while 里的计算太过复杂(cmath里的函数有点慢),所以我们需要用更简单的方法等效替代一下。
Code
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
long long t;
long long n,m,nn;
long long ans,k,i;
int main()
{
t=read();
while(t--)
{
ans=0;
i=1;
n=read(),m=read();
if(m==1)
{
cout<<0<<endl;
continue;
}
nn=n;
while(nn)//当nn>0
{
ans+=nn/m*i;
nn/=m;
i*=-1;
}
printf("%lld\n",n-ans);
}
return 0;
}
本蒟蒻第一次写题解,写的不好的请各位大佬多多谅解。望管理员大大给通过ヾ(≧O≦)〃嗷
work by Simon

浙公网安备 33010602011771号