题目链接:点击打开链接
题意:给定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; }