QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#697338 | #3840. Pass the Ball! | yzj123# | WA | 5ms | 16220kb | C++20 | 6.4kb | 2024-11-01 13:18:34 | 2024-11-01 13:18:35 |
Judging History
answer
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
#define int i64
using Poly = std::vector<int>;
using i128 = __int128;
//4179340454199820289
const int G = 3, Maxn = 2e6 + 10;
const i128 mod = 4179340454199820289;
int qmi(int a, i128 b = mod - 2) {
i128 res = 1;
while (b) {
if (b & 1) {
res = res * a % mod;
}
a = (i128)a * a % mod;
b >>= 1;
}
return res;
}
const i128 invG = qmi(G);
int tr[Maxn << 1], tf;
void tpre(int n) {
if (tf == n) return ;
tf = n;
for (int i = 0; i < n; i ++) {
tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0);
}
}
void NTT(int n, int *g, bool op) {
tpre(n);
static u64 f[Maxn << 1], w[Maxn << 1];
w[0] = 1;
for (int i = 0; i < n; i ++) {
f[i] = (((i128)mod << 5) + g[tr[i]]) % mod;
}
for (int l = 1; l < n; l <<= 1) {
i128 tG = qmi(op ? G : invG, (mod - 1) / (l + l));
for (int i = 1; i < l; i ++) w[i] = (i128)w[i - 1] * tG % mod;
for (int k = 0; k < n; k += l + l)
for (int p = 0; p < l; p ++) {
int tt = (i128)w[p] * f[k | l | p] % mod;
f[k | l | p] = f[k | p] + mod - tt;
f[k | p] += tt;
}
if (l == (1 << 10))
for (int i = 0; i < n; i ++) f[i] %= mod;
}
if (! op) {
i128 invn = qmi(n);
for(int i = 0; i < n; ++ i) {
g[i] = (i128)f[i] % mod * invn % mod;
}
} else {
for (int i = 0; i < n; ++ i) {
g[i] = f[i] % mod;
}
}
}
void px(int n, int *f, int *g) {
for (int i = 0; i < n; ++ i) {
f[i] = (i128)f[i] * g[i] % mod;
}
}
Poly operator +(const Poly &A, const Poly &B) {
Poly C = A;
C.resize(std::max(A.size(), B.size()));
for (int i = 0; i < B.size(); i ++) {
C[i] = (C[i] + B[i]) % mod;
}
return C;
}
Poly operator -(const Poly &A, const Poly &B) {
Poly C = A;
C.resize(std::max(A.size(),B.size()));
for (int i = 0; i < B.size(); i ++) {
C[i] = (C[i] + mod - B[i]) % mod;
}
return C;
}
Poly operator *(const int c, const Poly &A) {
Poly C;
C.resize(A.size());
for (int i = 0; i < A.size(); i ++) {
C[i] = 1ll * c * A[i] % mod;
}
return C;
}
int lim; // set.
Poly operator *(const Poly &A, const Poly &B) {
static int a[Maxn << 1], b[Maxn << 1];
for (int i = 0; i < A.size(); i ++) a[i] = A[i];
for (int i = 0; i < B.size(); i ++) b[i] = B[i];
Poly C;
C.resize(std::min(lim, (int)(A.size() + B.size() - 1)));
int n = 1;
for(n; n < A.size() + B.size() - 1; n <<= 1);
NTT(n, a, 1);
NTT(n, b, 1);
px(n, a, b);
NTT(n, a, 0);
for (int i = 0; i < C.size(); i ++) {
C[i] = a[i];
}
for (int i = 0; i <= n; i ++) {
a[i] = 0;
b[i] = 0;
}
return C;
}
void pinv(int n, const Poly &A, Poly &B) {
if (n == 1) B.push_back(qmi(A[0]));
else if (n & 1){
pinv(-- n, A, B);
int sav = 0;
for (int i = 0; i < n; i ++) {
sav = (sav + 1ll * B[i] * A[n - i] % mod) % mod;
}
B.push_back(1ll * sav * qmi(mod - A[0]) % mod);
} else {
pinv(n / 2, A, B);
Poly sA;
sA.resize(n);
for (int i = 0; i < n; i ++) {
sA[i] = A[i];
}
B = 2 * B - B * B * sA;
B.resize(n);
}
}
Poly pinv(const Poly &A) { // P-inv
Poly C;
pinv(A.size(), A, C);
return C;
}
int inv[Maxn];
void Init() {
inv[1] = 1;
for (int i = 2; i <= lim; i ++) {
inv[i] = 1ll * inv[mod % i] * (mod - mod / i) % mod;
}
}
Poly dao(const Poly &A) { // P-qiu-dao
Poly C = A;
for (int i = 1; i < C.size(); i ++) {
C[i - 1] = 1ll * C[i] * i % mod;
}
C.pop_back();
return C;
}
Poly ints(const Poly &A) { // P-ji-fen
Poly C = A;
for (int i = C.size() - 1; i; i --)
C[i] = 1ll * C[i - 1] * inv[i] % mod;
C[0] = 0;
return C;
}
Poly ln(const Poly &A) { // P-ln
return ints(dao(A) * pinv(A));
}
void pexp(int n, const Poly &A, Poly &B) {
if (n == 1) B.push_back(1);
else if (n & 1) {
pexp(n - 1, A, B);
n -= 2;
int sav = 0;
for (int i = 0; i <= n; i ++) {
sav = (sav + 1ll * (i + 1) * A[i + 1] % mod * B[n - i] % mod) % mod;
}
B.push_back(1ll * sav * inv[n + 1] % mod);
} else {
pexp(n / 2, A, B);
Poly lnB = B;
lnB.resize(n);
lnB = ln(lnB);
for (int i = 0; i < lnB.size(); i ++) {
lnB[i] = (mod + A[i] - lnB[i]) % mod;
}
lnB[0] ++;
B = B * lnB;
B.resize(n);
}
}
Poly pexp(const Poly &A) { // P-exp
Poly C;
pexp(A.size(), A, C);
return C;
}
using pii = std::array<int, 2>;
void solve() {
int n, q;
std::cin >> n >> q;
std::vector<int> a(n + 1);
for (int i = 1; i <= n; i ++) {
std::cin >> a[i];
}
std::vector<int> ans(q + 1), qu(q + 1);
for (int i = 1; i <= q; i ++) {
std::cin >> qu[i];
}
int B = std::sqrt(n);
std::vector<std::vector<int> > cir(B + 1, std::vector<int>(B + 1));
std::vector<bool> vis(n + 1);
for (int i = 1; i <= n; i ++) {
if (vis[i]) continue;
int j = i;
std::vector<pii> st;
while (! vis[j]) {
st.push_back({j, a[j]});
vis[j] = 1;
j = a[j];
}
int siz = st.size();
Poly f(siz * 2), g(siz);
for (int i = 0; i < siz; i ++) {
f[i] = st[i][0];
f[i + siz] = f[i];
// std::cout << f[i] << ' ';
}
// std::cout << '\n';
for (int i = 0; i < siz; i ++) {
g[i] = st[siz - i - 1][1];
// std::cout << g[i] << ' ';
}
// std::cout << '\n';
lim = 4 * siz;
auto res = f * g;
// std::cout << siz << '\n';
// for (int j = 0; j <= siz + siz + 1; j ++) {
// std::cout << res[j] << ' ';
// }
// std::cout << '\n';
if (st.size() > B) {
for (int j = 1; j <= q; j ++) {
int o = qu[j];
o %= siz;
ans[j] += res[siz + o]; // 1 2 3 0
}
} else {
// cir[siz]
for (int j = 0; j < siz; j ++) {
cir[siz][j] += res[siz + j];
}
}
}
for (int i = 1; i <= q; i ++) {
for (int j = 1; j <= B; j ++) {
ans[i] += cir[j][qu[i] % j];
}
}
for (int i = 1; i <= q; i ++) {
std::cout << ans[i] << '\n';
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
//std::cin >> t;
while (t --) {
solve();
}
return 0;
}
/*
4 4
2 4 1 3
1
2
3
4
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 13800kb
input:
4 4 2 4 1 3 1 2 3 4
output:
25 20 25 30
result:
ok 4 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 13792kb
input:
3 6 2 3 1 1 2 3 999999998 999999999 1000000000
output:
11 11 14 11 14 11
result:
ok 6 lines
Test #3:
score: 0
Accepted
time: 0ms
memory: 13992kb
input:
3 6 3 1 2 1 2 3 999999998 999999999 1000000000
output:
11 11 14 11 14 11
result:
ok 6 lines
Test #4:
score: -100
Wrong Answer
time: 5ms
memory: 16220kb
input:
1000 10000 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100...
output:
1308481768752303428 3194215467094442871 2690208870575837830 582793761525126492 261196047235238901 3536502234026338049 2424873991545923560 3516835685953597417 168801110111218757 3652782466199994987 1448769273924133123 1456805716496720549 3953258197783317751 574232795374918607 1691155241770098009 2267...
result:
wrong answer 1st lines differ - expected: '333334000', found: '1308481768752303428'