#include<bits/stdc++.h> usingnamespace std; #define ll long long constint N = 2e5 + 10; constint INF = 0x3f3f3f3f; int T; int n, p[N], c[N]; int vis[N], cir[N], len; boolcheck(int l){ for (int i = 0; i < l; i++) { bool ok = 1; int u = i; while ((u + l) % len != i) { if (c[cir[u]] != c[cir[i]])ok = 0; u = (u + l) % len; } if (c[cir[u]] != c[cir[i]])ok = 0; if (ok)returntrue; } returnfalse; } intmain(){ scanf("%d", &T); while (T--) { scanf("%d", &n); fill(vis + 1, vis + n + 1, 0); int ans = INF; for (int i = 1; i <= n; i++)scanf("%d", &p[i]); for (int i = 1; i <= n; i++)scanf("%d", &c[i]); for (int i = 1; i <= n; i++) { if (vis[i])continue; int u = i; len = 0; while (p[u] != i) { cir[len++] = u; vis[u] = 1; u = p[u]; } cir[len++] = u; vis[u] = 1; for (int j = 1; j*j <= len; j++) { if (len%j)continue; if (check(j))ans = min(ans, j); if (check(len / j))ans = min(ans, len / j); } } printf("%d\n", ans); } return0; }
E. Count The Blocks
题意:写下 0 到 10n−1 的所有数,且补前导0,使得每个数长度都为 n,对 i 从 1 到 n,不考虑不同数之间,问写下的数字中有多少的长为 i 的连续相等数块。
既然每一位都能从0写到9,那么每个数就是一样的了,可以算0的值,再乘10.
长度为 i 的块有 n−i+1 个,放入1块后,剩下 n−i 位,其中与块相邻的两位有9种取法,其他的有10种取法。
#include<bits/stdc++.h> usingnamespace std; #define ll long long constint N = 2e5 + 10; constint INF = 0x3f3f3f3f; const ll mod = 998244353; ll fact[N], inv[N]; ll power(ll a, ll x){ ll ans = 1; while (x) { if (x & 1) ans = (ans * a) % mod; a = (a * a) % mod; x >>= 1; } return ans; } intmain(){ scanf("%lld", &n); init(); for (ll i = 1; i <= n; i++) { if (i == n) { printf("10\n"); } elseif (i == n - 1)printf("180 "); else{ ll ans = (power(10, n - i - 1) * 180) % mod; ans = (ans + (n - i - 1) * 9 * 9 * 10 % mod*power(10, n - i - 2) % mod) % mod; printf("%lld ", ans); } } return0; }