洛谷P7893

# luoguP7893

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

posted @ 2021-11-14 21:49  Simon_...sun  阅读(87)  评论(0)    收藏  举报