Atcoder AGC011E : Increasing Numbers

传送门

题解:
妙啊。

一个上升序列可以拆分为9个形如 1111111 1111111 的形式。 然后列出式子:

n=i=19k10ai19 n = ∑ i = 1 9 k 10 a i − 1 9

移一下项:

9n+9k=i=19k10ai 9 n + 9 k = ∑ i = 1 9 k 10 a i

枚举 k k ,然后就做完了。

#include 
using namespace std;

const int RLEN=1<<18|1;
inline char nc() {
    static char ibuf[RLEN],*ib,*ob;
    (ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
    char ch=nc(); int i=0,f=1;
    while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
    while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
    return i*f;
}

const int N=5e5+50;
int n,A[N],sum;
char ch[N];
int main() {
    scanf("%s",ch); n=strlen(ch);
    for(int i=0;i1]=ch[i]-'0', sum+=A[n-i-1];
    sum*=9;
    for(int i=0;i9;
    for(int i=0;iif(A[i]>=10) {
            sum-=A[i];
            sum-=A[i+1];
            A[i+1]+=A[i]/10;
            A[i]%=10;
            sum+=A[i];
            sum+=A[i+1];
            if(i+1>=n) ++n;
        }
    }
    for(int k=1;k<=n;++k) {
        A[0]+=9; sum+=9;
        for(int i=0;;++i) {
            if(A[i]>=10) {
                sum-=A[i];
                sum-=A[i+1];
                A[i+1]+=A[i]/10;
                A[i]%=10;
                sum+=A[i];
                sum+=A[i+1];
                if(i+1>=n) ++n;
            } else break;
        }
        if(sum<=9*k && sum%9==0) {cout<'\n'; return 0;}
    }
}

你可能感兴趣的:(Atcoder AGC011E : Increasing Numbers)