JPGOJCZX @ 2024-11-15 20:44:52
已经卡了
原题:CF GYM 102769J Jewel Splitting
#define LOCAL
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#define int long long
#define pc putchar
#define gc getchar
namespace IO{
#ifndef LOCAL
#define SIZE (1 << 20)
char buf1[SIZE], buf2[SIZE], *p1 = buf1, *p2 = buf1, *p3 = buf2;
#define gc() (p1 == p2 && (p2 = (p1 = buf1) + fread(buf1, 1, SIZE, stdin), p1 == p2) ? EOF : *p1++)
#define flush() (fwrite(p3 = buf2, 1, SIZE, stdout))
#define pc(ch) (p3 == buf2 + SIZE && flush(), *p3++ = (ch))
class Flush{public : ~ Flush(){flush();}}_;
#endif
template <typename type>
inline void rd(type &x){
x = 0; bool f(0); char c = gc();
while(!isdigit(c))f ^= c == '-', c = gc();
while(isdigit(c))x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
f ? x = - x : 0;
}
template <typename type>
inline void wt(type x){
x < 0 ? x = - x, pc('-') : 0; static short st[50], top(0);
do st[++top] = x % 10, x /= 10; while(x);
while(top)pc(st[top--] ^ 48);
}
inline char rd(char &c){return c = gc();}
inline char wt(const char &c){return pc(c);}
template <typename type, typename ...T>
inline void rd(type &x, T &...y){rd(x), rd(y...);}
template <typename type, typename ...T>
inline void wt(type x, T ...y){wt(x), pc(' '), wt(y...), sizeof ...(y) ^ 1 ? 0 : pc('\n');}
#ifndef LOCAL
#undef SIZE
#undef gc
#undef pc
#undef flush
#endif
}
using namespace IO;
using namespace std;
using namespace __gnu_pbds;
const int N = 3e5 + 9;
inline int extend_gcd(int a, int b, int &x, int &y){
if(b == 0){
x = 1;
y = 0;
return 0;
}
int d = extend_gcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
inline int mod_inverse(int a, int m){
int x, y;
extend_gcd(a, m, x, y);
return (x % m + m) % m;
}
int B[N], H[N], base = 131, MOD1 = 998244353, MOD2 = (1ll << 61) - 1;
inline __int128 sub(__int128 x, __int128 y){
return x - y < 0 ? x - y + MOD2 : x - y;
}
inline __int128 mod(__int128 x){
return sub((MOD2 & x) + (x >> 61), MOD2);
}
inline __int128 Hash(int l, int r){
return mod(sub(__int128(H[r]), mod(__int128(H[l - 1]) * __int128(B[r - l + 1]))));
}
int T, n, ans, ji[N], inv[N], cnt = 1;
char ch[N];
inline void solve(){
ans = 0;
gp_hash_table <int, bool> h2{};
scanf("%s", ch + 1);
n = strlen(ch + 1);
B[0] = 1;
for(register int i = 1; i <= n; ++i){
H[i] = mod(mod(__int128(H[i - 1]) * __int128(base)) + ch[i]);
B[i] = mod(__int128(B[i - 1]) * __int128(base));
}
for(register int d = 1; d <= n; ++d){
gp_hash_table <unsigned long long, int> h1{};
int quo = n / d, rem = n % d, val = ji[quo];
unsigned long long tmp = 0;
for(register int i = rem + 1; i <= n; i += d){
__int128 num = Hash(i, i + d - 1);
tmp += mod(num * num * num * num);
if(h1[num])
val = val * ji[h1[num]] % MOD1;
h1[num]++;
val = val * inv[h1[num]] % MOD1;
}
if(!h2[tmp]){
h2[tmp] = true;
ans = (ans + val) % MOD1;
}
for(register int k = 1; k <= quo; ++k){
__int128 num1 = Hash((k - 1) * d + rem + 1, k * d + rem), num2 = Hash((k - 1) * d + 1, k * d);
val = val * ji[h1[num1]] % MOD1;
if(h1[num2] != 0)
val = val * ji[h1[num2]] % MOD1;
h1[num1]--;
h1[num2]++;
if(h1[num1] != 0)
val = val * inv[h1[num1]] % MOD1;
val = val * inv[h1[num2]] % MOD1;
tmp += mod(num2 * num2 * num2 * num2) - mod(num1 * num1 * num1 * num1);
if(h2[tmp])
continue;
h2[tmp] = true;
ans = (ans + val) % MOD1;
}
}
pc('C');
pc('a');
pc('s');
pc('e');
pc(' ');
pc('#');
wt(cnt);
pc(':');
pc(' ');
wt(ans % MOD1);
pc('\n');
cnt++;
}
signed main(){
ji[1] = 1;
for(register int i = 2; i < N; ++i)
ji[i] = ji[i - 1] * i % MOD1;
inv[N - 1] = mod_inverse(ji[N - 1], MOD1);
for(register int i = N - 2; i >= 1; --i)
inv[i] = inv[i + 1] * (i + 1) % MOD1;
rd(T);
while(T--)
solve();
return 0;
}
玄关qwq