题目链接:点击打开链接
题意:给定k,p,求一个各系数都为小于k的非负数的多项式f(x),使得存在一个多项式q(x),有f(x) = q(x)(x+k)+p
思路:
利用多项式余数定理,即若f(x) % (x - k) = p,则f(k) = p。
这里k用-k代替即得到所求多项式为f(-k) = p,可以看作是一个-k进制下的p的表示。先求k进制下p的表示,对于每个奇数位上的数进行检查(因为-k的奇数次幂为负数)。假设某奇数位a上k进制下p的表示大于0,即需要加上一个 该位上的数(不妨设为b)*k^a,也就是加上一个 k^(a+1) - (k-b)*k^a,这里的b显然小于k。而后对后两位数进行同样的检查即可。
AC代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
#define FSIO ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a) cout<<"DEBUG: "<<(a)<<endl;
long long num[100];
long long k, p;
long long mark[100];
void check(int p)
{
if(p<=90&&mark[p]>=k)
{
mark[p+1]+=k-mark[p]/k;
mark[p+2]+=1;
mark[p]%=k;
check(p+1);
check(p+2);
}
else
return;
}
int main()
{
FSIO;
while(cin>>p>>k)
{
memset(mark,0,sizeof(mark));
num[0]=1;
int cur=0;
while(num[cur]<p) cur++, num[cur]=num[cur-1]*k;
for(int i=cur;i>=0;--i)
{
if(p/num[i]!=0)
{
mark[i] = p/num[i];
if(i%2==1)
{
mark[i] = k-mark[i];
mark[i+1]++;
check(i+1);
}
p%=num[i];
}
else
{
mark[i] = 0;
}
}
cur = 80;
while(mark[cur]==0) cur--;
cout<<cur+1<<endl;
for(int i=0;i<cur;i++)
cout<<mark[i]<<" ";
cout<<mark[cur]<<endl;
}
return 0;
}