首页 > 其他分享 >arc129 C - Multiple of 7

arc129 C - Multiple of 7

时间:2023-01-28 18:33:50浏览次数:60  
标签:end .. int arc129 ++ while ans Multiple

题意:

给定 \(n\),请构造一个长度不超过 \(1e6\) 的 1~9 串 \(s\),满足视为数字时被 \(7\) 整除的子串恰有 \(n\) 个

\(n\le 1e6\)

思路:

\(s[l..r]\) 能被 \(7\) 整除,即 \(7 | \frac{s[l..end]-s[r+1..end]}{10^?}\)

分母与 \(7\) 互质,所以只需 \(s[l..end]\equiv s[r+1..end]\pmod 7\)

设 \(a_i:=s[i..end]\mod 7\),设 \(c[]\) 为数组 \(a[]\) 的桶,即 \(c_v=\sum\limits_i [a_i=v]\)

那么我们要构造数组 \(c[]\),使得 \(n=\sum\limits_i c_i(c_i-1)/2\)

问题是怎么构造?如果你经验丰富(呃呃),或者你打个表(呃呃),就能发现在这题的范围内,只需贪心地每次找满足 \(c_i(c_i-1)/2\) 最大的 \(c_i\)

ps. 事实上 \(x(x-1)/2\) 恰好是三角形数,\(c[]\) 的存在性由费马多边形数定理(Fermat polygonal number theorem)保证。详见 多边形数、费马多边形数定理、四平方和定理与华林问题

ps. 有了 \(c[]\) 后,从右到左构造答案字符串,每一位从 \(1\sim 7\) 试填即可

void sol() {
    int n; cin >> n;
    vector<int> c;
    while(n) {
        int x = 2; while(x * (x + 1) / 2 <= n) x++;
        c.push_back(x);
        n -= x * (x - 1) / 2;
    }
    c[0]--; // s[|s|+1]本就是0,不用搞
    vector<int> ans;
    int r = 0, w = 1;
    for(int i = 0; i < c.size(); i++) while(c[i]--) {
        int x = 1; while((r + x * w) % 7 != i) x++;
        assert(x < 8);
        ans.push_back(x);
        r = (r + x * w) % 7, w = w * 10 % 7;
    }
    for(auto i = ans.rbegin(); i != ans.rend(); i++)
        cout << *i;
}

标签:end,..,int,arc129,++,while,ans,Multiple
From: https://www.cnblogs.com/wushansinger/p/17071081.html

相关文章