模拟赛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;} 

完结撒花

posted @ 2018-10-18 18:51  ASDIC减除  阅读(139)  评论(0编辑  收藏  举报