A
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
char ch; while(!isdigit(ch=getchar()));
for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0');
}
const int mod = 998244353;
const int MAXN = 500005;
int T, n, p[MAXN], cnt[MAXN], fac[MAXN], inv[MAXN], mn, f[MAXN];
bool vis[MAXN];
inline int qpow(int a, int b) {
int re = 1; (b += mod-1) %= mod-1;
for(; b; b>>=1, a=1ll*a*a%mod)if(b&1)re=1ll*re*a%mod;
return re;
}
inline int C(int n, int m) { return n < m ? 0 : 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod; }
int main () {
freopen("A.in", "r", stdin);
freopen("A.out", "w", stdout);
fac[0] = inv[0] = fac[1] = inv[1] = 1;
for(int i = 2; i < MAXN; ++i) fac[i] = 1ll*fac[i-1]*i%mod, inv[i] = 1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i = 2; i < MAXN; ++i) inv[i] = 1ll*inv[i-1]*inv[i]%mod;
for(read(T); T--; ) {
read(n); mn = n+1;
for(int i = 1; i <= n; ++i) read(p[i]), cnt[i] = f[i] = vis[i] = 0;
for(int i = 1; i <= n; ++i) if(!vis[i]) {
int sz = vis[i] = 1;
for(int j = p[i]; j != i; j = p[j])++sz, vis[j] = 1;
mn = min(mn, sz); ++cnt[sz];
}
bool flg = 0;
for(int i = 1; i <= n; ++i) if(cnt[i] && i%mn) flg = 1;
if(mn > 2 || flg) { puts("0"); continue; }
for(int i = 1; i <= n; ++i)
for(int j = 2*i; j <= n; j += i)
f[j] += cnt[i]*i;
int ans = qpow(cnt[mn]*mn, cnt[mn]-2+(mn==2));
for(int i = mn+1; i <= n; ++i) if(cnt[i]) {
int s = 0;
for(int k = 1; k <= cnt[i]; ++k)
s = (s + 1ll * qpow(cnt[i]*i, cnt[i]-k) * qpow(f[i], k) % mod * C(cnt[i]-1, k-1)) % mod;
ans = 1ll * ans * s % mod;
}
printf("%d\n", ans);
}
}
B
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x) {
char ch; while(!isdigit(ch=getchar()));
for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0');
}
typedef long long LL;
const int MAXN = 500005;
const LL inf = 1ll<<60;
int n, a[MAXN], b[MAXN], bin[MAXN], tot;
struct node {
LL a, b, c, lv; // lv = left_point_val
node(LL a=0, LL b=0, LL c=-inf):a(a), b(b), c(c){}
}t[MAXN<<2];
void give(int i, int l, node v) {
if(v.c > -inf) t[i].a = 0, t[i].b = 0, t[i].c = t[i].lv = v.c;
t[i].a += v.a;
t[i].b += v.b;
t[i].lv += v.a + v.b * bin[l];
}
inline void pd(int i, int l, int mid) {
if(t[i].a || t[i].b || t[i].c > -inf) {
give(i<<1, l, t[i]);
give(i<<1|1, mid+1, t[i]);
t[i].a = t[i].b = 0, t[i].c = -inf;
}
}
void add(int i, int l, int r, int x, int y, node v) {
if(x <= l && r <= y) { give(i, l, v); return; }
int mid = (l + r) >> 1; pd(i, l, mid);
if(x <= mid) add(i<<1, l, mid, x, y, v);
if(y > mid) add(i<<1|1, mid+1, r, x, y, v);
t[i].lv = t[i<<1].lv;
}
LL qry(int i, int l, int r, int x) {
if(l == r) return t[i].lv;
int mid = (l + r) >> 1; pd(i, l, mid);
return x <= mid ? qry(i<<1, l, mid, x) : qry(i<<1|1, mid+1, r, x);
}
int solve(int i, int l, int r, int x, LL val) {
if(x > r) return -1;
if(l == r) return t[i].lv < val ? l : -1;
int mid = (l + r) >> 1; pd(i, l, mid);
if(x > mid || t[i<<1|1].lv < val) return solve(i<<1|1, mid+1, r, x, val);
return solve(i<<1, l, mid, x, val);
}
int main(){
read(n);
for(int i = 1; i <= n; ++i) read(a[i]), bin[++tot] = a[i];
for(int i = 1; i <= n; ++i) read(b[i]);
sort(bin + 1, bin + tot + 1);
tot = unique(bin + 1, bin + tot + 1) - bin - 1;
for(int i = 1; i <= n; ++i) {
int A = lower_bound(bin + 1, bin + tot + 1, a[i]) - bin;
add(1, 1, tot, 1, A, node(b[i]-a[i], 1));
LL val = qry(1, 1, tot, A);
int pos = solve(1, 1, tot, A+1, val);
if(pos > A) add(1, 1, tot, A+1, pos, node(0, 0, val));
}
printf("%lld\n", qry(1, 1, tot, tot));
}
C
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 15005;
int T, n, a[MAXN], rk[MAXN];
void Do(string op, int flg) {
printf("%d %s\n", flg, op.c_str());
vector<int>vec[2];
for(int i = 0; i < n; ++i) if(op[i] == '1') vec[(a[i]&1)^flg].push_back(a[i]);
vec[0].insert(vec[0].end(), vec[1].begin(), vec[1].end());
for(int i = 0, j = 0; i < n; ++i) if(op[i] == '1') a[i] = vec[0][j++];
}
int main () {
scanf("%d", &T);
while(T--) {
scanf("%d%*d", &n);
for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
int mid = (n+1)/2, x = 0;
for(int j = 0; x < mid; j+=2, x+=2) rk[x] = j;
for(int j = 1; x < n; j+=2, x+=2) rk[x] = j;
x = (n&1) ? n-2 : n-1;
for(int j = (n&1)?2:0; x >= mid; j+=2, x-=2) rk[x] = j;
for(int j = 1; x > 0; j+=2, x-=2) rk[x] = j;
puts("28");
Do(string(n, '1'), 0);
for(int i = 0; i < 13; ++i) {
string op(n, '0');
for(int j = 0; j < n; ++j) if(rk[a[j]]>>i&1) op[j] = '1';
Do(op, 1); Do(string(n, '1'), 0);
}
string op(n, '0');
for(int i = 0; i < n; ++i) if(a[i] != i) op[i] = '1';
Do(op, 1);
}
}