模拟赛20181016 简单高精+推式子
我们发现一条性质,第n项实在进行完第n次操作后确定的,那么由性质倒推
设当前元素的全长ans,那么前n-1可以看成都是完整的块,拥有相同的长度,那么我们可以发现,最后一段是多余的一段,而前n-1段实际上是由一段/2得到的
那么我们可以大力发现得到一条向前倒推的公式
n -> n+n/i*i == 2*n-n%i n%i!=0
2*n-i n%i==0
然后发现会爆long long那么写一个高精度,只会用到高精减低精,高精模低精,高精乘低精,非常完美那就比较容易写了
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) #define dec(i,x,y) for(register int i=x;i>=y;i--) using namespace std; const int N=10050; int n,a[N],b[N],c[N]; int top1,top2,top3; inline void sudo(int minus){top2=top3=0; memset(b,0,sizeof b); memset(c,0,sizeof c); //二倍 rep(i,1,top1){ b[i]+=a[i]*2;b[i+1]+=b[i]/10;b[i]=b[i]%10;} top2=top1;if(b[top2+1]) top2++; //输入 for(int i=1;;i++){ c[++top3]=minus%10,minus/=10;if(!minus) break;} //减法 rep(i,1,top3){ if(b[i]>c[i]) b[i]-=c[i],c[i]=0; else b[i+1]-=1,b[i]+=10,b[i]-=c[i],c[i]=0;} rep(i,1,top2-1) if(b[i]<0) b[i]+=10,b[i+1]-=1; //挪移 if(!b[top2]) top2--; rep(i,1,top2) a[i]=b[i];top1=top2;} inline void check(int mod){ int k=1,ans=0; rep(i,1,top1) ans=(ans+a[i]*k)%mod,k=k*10%mod; if(ans) sudo(ans);else sudo(mod);} inline void init(){int s=n; for(int i=1;;i++){ a[++top1]=s%10,s/=10;if(!s) break;}} int main(){ freopen("delete.in","r",stdin); freopen("delete.out","w",stdout); scanf("%d",&n); init(); dec(i,n-1,1)check(i); dec(i,top1,1)printf("%d",a[i]); printf("\n");return 0;}
完结撒花