[ARC129C] Multiple of 7
首先我们看到了要求是 \(7\) 的倍数,那么典中典的转化就是转化为 \(x \equiv 0 \pmod {7}\)。
区间问题不好考虑,考虑采用差分(注意这个题目你要差分的话,是后缀的差,这样最低位才对齐)。
也就是说,对于一个后缀 \(i\),它的贡献是 \(\sum\limits_{j>i} [suf_i \equiv suf_j \pmod 7]\)。
进一步地,设 \(c_i\) 为 \(\sum\limits_{j \in [1,|s|]} [suf_j \equiv i \pmod {7}]\),要求即为 \(\sum\limits_{i \in [0,7)} \frac {c_i (c_i - 1)} {2} = n \iff \sum\limits_{i \in [0,7)} c_i (c_i - 1) = 2n\)。
也就是我们有 \(7\) 个形如 \(x(x-1)\) 的数,要求凑出 \(2\times 10^6\) 内的所有偶数。
考虑一次 \(n \leftarrow n - \lfloor \sqrt n \rfloor(\lfloor \sqrt n \rfloor - 1)\),会使 \(n\) 变为 \(\sqrt n\) 量级,相当于取对数后指数除以二,大概可行。
首先我们有粗略估计,使用上文方法减小至小范围后,搜索或者脑内构造。
精细考虑太麻烦,我们使用高科技,链接,尝试发现嵌套 \(4\) 层,剩下 \(3\) 次一定可以凑出 \(12\) 内所有偶数。
代码细节:天然存在一个余数为 \(0\) 的,所以 \(c_0\) 得减一。
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned;
#define all(x) x.begin(),x.end()
#define r_all(x) x.rbegin(),x.rend()
int n , c[10];
int dfs(int x , int i = 0){
if(i == 4) return x;
int y = floor(sqrt(x));
c[i] = y;
return dfs(x - y * (y - 1) , i + 1);
}
int dfs2(int rest , int i = 6){
if(rest < 0) return 0;
if(rest == 0) return 1;
if(i < 4) return 0;
int res = 0;
for(int j : {2 , 3 , 4}){
if(dfs2(rest - j * (j - 1) , i - 1)) {
res = 1; c[i] = j;
break;
}
}
return res;
}
signed main() {
#ifdef LOCAL
#elif defined(ONLINE_JUDGE)
#else
#endif
ios::sync_with_stdio(0); cin.tie(0);
cin >> n; n <<= 1;
int tmp = dfs(n);
dfs2(tmp);
if(c[0]) -- c[0];
vector<int> s;
int pre = 0 , rad = 1;
for(int i = 0; i < 7; ++ i){
for(int j = 1; j <= c[i]; ++ j){
int x = (i - pre + 7) * rad % 7;
s.push_back(x);
(rad *= 5) %= 7;
pre = i;
}
}
for_each(r_all(s) , [] (int x) {cout << (x ? x : 7);});
return 0;
}