QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#431850 | #8312. Fly Me To The Moon | Slongod | WA | 1748ms | 95304kb | C++17 | 10.1kb | 2024-06-06 10:47:41 | 2024-06-06 10:47:42 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
namespace Poly
{
const int mod = 998244353 , W = 23 , N = (1<<W) + 37;
struct poly {
vector <int> f; int deg;
void red(int d){deg = d; f.resize(d,0);}
poly(int x = 1){red(x);}
int& operator [] (int x){return f[x];}
const int& operator [] (int x) const {assert(x < deg); return f[x];}
void operator <<= (int x) {
red(deg + x);
for (int i = deg - 1; i >= x; i++){f[i] = f[i-x];}
for (int i = 0; i < x; i++){f[i] = 0;}
}
void operator >>= (int x) {
for (int i = 0; i + x < deg; i++){f[i] = f[i+x];} red(deg - x);
}
poly recut(int len){poly re = *this; re.red(len); return re;}
};
poly operator + (poly a , int x){a[0] = (1ll * a[0] + x + mod) % mod; return a;}
poly operator + (int x , poly a){a[0] = (1ll * a[0] + x + mod) % mod; return a;}
poly operator + (const poly &a , const poly &b) {
poly re(max(a.deg , b.deg));
for (int i = 0; i < re.deg; i++) {
re[i] = (a[i] + b[i]) % mod;
} return re;
}
poly operator - (const poly &a) {
poly re = a;
for (int i = 0; i < re.deg; i++) {
re[i] = (mod - re[i]) % mod;
} return re;
}
poly operator - (const poly &a , const poly &b) {
return a + (-b);
}
poly operator - (const poly &a , int y){return a + (-y);}
poly operator - (int x , const poly &a){return x + (-a);}
int fw[W] , ifw[N] , invp[N] , dp[N];
inline int qkpow(int x , int y){int s; for(s=1;y;y/=2,x=1ll*x*x%mod){if(y&1){s=1ll*s*x%mod;}}return s;}
inline void init()
{
invp[1] = 1;
for (int i = 2; i < N; i++){invp[i] = 1ll * (mod - 1) * (mod / i) % mod * invp[mod%i] % mod;}
for (int i = 0; i < W; i++){fw[i] = qkpow(3 , (mod-1)/(1<<(i+1)));}
for (int i = 0; i < W; i++){ifw[i] = qkpow(fw[i] , mod - 2);}
}
inline void ntt(poly &f , int k , int opt)
{
for (int i = 1; i < (1 << k); i++){dp[i] = (dp[i>>1]>>1) | ((i&1)<<(k-1));}
for (int i = 0; i < (1 << k); i++){if (i < dp[i]){swap(f[i] , f[dp[i]]);}}
for (int i = 1 , ct = 0; i < (1 << k); i <<= 1 , ct++) {
for (int j = 0 , w = opt == 1 ? fw[ct] : ifw[ct]; j < (1 << k); j += (i << 1)) {
for (int l = 0 , now = 1; l < i; l++ , now = 1ll * now * w % mod) {
int x = f[l+j] , y = 1ll * f[l+j+i] * now % mod;
f[l+j] = (x + y) % mod; f[l+j+i] = (x - y + mod) % mod;
}
}
}
if (opt == -1) {
int invn = qkpow((1 << k) , mod - 2);
for (int i = 0; i < (1 << k); i++) {
f[i] = 1ll * f[i] * invn % mod;
}
}
}
//长度为 n 和长度为 m 的多项式相乘得到一个长度为 n+m-1 的多项式
poly operator * (poly a , poly b)
{
int len = a.deg + b.deg - 1 , k = 0;
while((1<<k) <= len){k++;} a.red(1<<k); b.red(1<<k);
ntt(a , k , 1); ntt(b , k , 1); poly re(1<<k);
for (int i = 0; i < (1 << k); i++){re[i] = 1ll * a[i] * b[i] % mod;}
ntt(re , k , -1); re.red(len); return re;
}
poly operator * (poly a , int y){for (int i = 0; i < a.deg; i++){a[i] = 1ll * a[i] * y % mod;} return a;}
poly operator * (int y , poly a){for (int i = 0; i < a.deg; i++){a[i] = 1ll * a[i] * y % mod;} return a;}
//求出一个 g,令 fg=1(mod x^f.deg)
poly doinv(poly f , int k)
{
if (!k){poly re(1); re[0] = qkpow(f[0] , mod - 2); return re;}
poly g = doinv(f.recut(1<<k-1) , k - 1);
g.red(1<<(k+1)); f.red(1<<(k+1));
ntt(g , k+1 , 1); ntt(f , k+1 , 1);
for (int i = 0; i < (1 << (k+1)); i++) {
g[i] = (1ll * g[i] * (2 - 1ll * f[i] * g[i] % mod + mod) % mod);
} ntt(g , k+1 , -1); return g.recut(1<<k);
}
poly inv(poly f)
{
int k = 0 , dg = f.deg; while((1<<k) < dg){k++;}
f.red(1<<k); return doinv(f , k).recut(dg);
}
//返回 f 的导数,长度为 f.deg-1
poly der(const poly &f)
{
if (f.deg == 1){return poly();}
poly re(f.deg - 1);
for (int i = 1; i < f.deg; i++) {
re[i-1] = 1ll * f[i] * i % mod;
} return re;
}
//返回 f 的不定积分,长度为 f.deg+1
poly integ(const poly &f)
{
poly re(f.deg + 1);
for (int i = 0; i < f.deg; i++) {
re[i+1] = 1ll * f[i] * invp[i+1] % mod;
} return re;
}
//返回 g = ln(f) mod x^f.deg
poly ln(const poly &f){return integ(der(f) * inv(f)).recut(f.deg);}
//返回 g = exp(f) mod x^f.deg
poly doexp(poly f , int k)
{
if (!k){poly re(1); re[0] = 1; return re;}
poly g = doexp(f.recut((1<<(k-1))) , k-1);
g.red(1<<k); return g * (1 + f - ln(g)).recut(1<<(k+1));
}
poly exp(poly f)
{
int dg = f.deg , k = 0; while((1<<k) < dg){k++;}
f.red(1<<k); return doexp(f , k).recut(dg);
}
/*
在使用前调用 init()
*/
namespace Poly2D
{
struct poly2d {
vector<poly> f; int degx , degy;
void red(int dx , int dy) {
degx = dx; degy = dy; f.resize(dx , poly(dy));
for (int i = 0; i < dx; i++){f[i].red(dy);}
}
poly2d(int dx = 1 , int dy = 1){red(dx , dy);}
poly& operator [] (int x){return f[x];}
const poly& operator [] (int x) const {return f[x];}
poly2d recut(int dx , int dy){poly2d re = *this; re.red(dx , dy); return re;}
void nttx(int kx , int ky , int opt)
{
for (int i = 0; i < (1<<kx); i++) {
Poly::ntt(f[i] , ky , opt);
}
}
void ntty(int kx , int ky , int opt)
{
poly t(1<<kx);
for (int j = 0; j < (1<<ky); j++) {
for (int i = 0; i < (1<<kx); i++) {
t[i] = f[i][j];
} Poly::ntt(t , kx , opt);
for (int i = 0; i < (1<<kx); i++) {
f[i][j] = t[i];
}
}
}
void ntt(int kx , int ky , int opt)
{
if (opt == 1){nttx(kx , ky , 1); ntty(kx , ky , 1);}
else{ntty(kx , ky , -1); nttx(kx , ky , -1);}
}
};
poly2d operator + (poly2d a , poly2d b)
{
int dx = max(a.degx , b.degx) , dy = max(a.degy , b.degy);
a.red(dx , dy); b.red(dx , dy);
for (int i = 0; i < dx; i++) {
for (int j = 0; j < dy; j++) {
a[i][j] = (a[i][j] + b[i][j]) % mod;
}
} return a;
}
poly2d operator + (poly2d a , int x){a[0][0] = (a[0][0] + x) % mod; return a;}
poly2d operator + (int x , poly2d a){a[0][0] = (a[0][0] + x) % mod; return a;}
poly2d operator - (poly2d a)
{
for (int i = 0; i < a.degx; i++) {
for (int j = 0; j < a.degy; j++) {
a[i][j] = (mod - a[i][j]);
}
} return a;
}
poly2d operator - (const poly2d &a , const poly2d &b){return a + (-b);}
poly2d operator - (const poly2d &a , int y){return a + (-y);}
poly2d operator - (int x , const poly2d &a){return x + (-a);}
poly2d operator * (poly2d a , poly2d b)
{
int dx = a.degx + b.degx - 1 , dy = a.degy + b.degy - 1;
int kx = 0; while((1<<kx) <= dx){kx++;}
int ky = 0; while((1<<ky) <= dy){ky++;}
a.red(1<<kx , 1<<ky); b.red(1<<kx , 1<<ky);
a.ntt(kx , ky , 1); b.ntt(kx , ky , 1);
for (int i = 0; i < (1<<kx); i++) {
for (int j = 0; j < (1<<ky); j++) {
a[i][j] = 1ll * a[i][j] * b[i][j] % mod;
}
} a.ntt(kx , ky , -1); a.red(dx , dy); return a;
}
//返回一个 fg=1 mod(x^f.degx , y^f.degy)
poly2d doinv(poly2d f , int k)
{
if (!k){poly2d g(1); g[0] = inv(f[0]); return g;}
poly2d g = doinv(f.recut(1<<(k-1) , f.degy) , k - 1);
int dy = f.degy , tk = 0; while((1<<tk) < (dy<<1)){tk++;}
g.red(1<<(k+1) , 1<<tk); f.red(1<<(k+1) , 1<<tk);
g.ntt(k+1 , tk , 1); f.ntt(k+1 , tk , 1);
for (int i = 0; i < (1<<(k+1)); i++) {
for (int j = 0; j < (1<<tk); j++) {
g[i][j] = 1ll * g[i][j] * (2 - 1ll * f[i][j] * g[i][j] % mod + mod) % mod;
}
} g.ntt(k+1 , tk , -1); return g.recut(1<<k , dy);
}
poly2d inv(poly2d f)
{
int k = 0 , dx = f.degx; while((1<<k)< dx){k++;}
return doinv(f , k).recut(dx , f.degy);
}
}
}
using namespace Poly;
using namespace Poly::Poly2D;
const int maxn = 1001; Poly2D::poly2d f(maxn,maxn);
int n , m , X[1001] , Y[1001] , F[1001];
int dfs(int x)
{
if (F[x] != -1){return F[x];}
int ans = f[X[x]][Y[x]];
for (int i = 0; i < m; i++) {
if (i == x or X[i] > X[x] or Y[i] > Y[x]){continue;}
ans = (ans - 1ll * dfs(i) * f[X[x]-X[i]][Y[x]-Y[i]] % mod + mod) % mod;
} return F[x] = ans;
}
int main()
{
ios :: sync_with_stdio(0);
cin.tie(0) , cout.tie(0);
memset(F , -1 , sizeof(F));cin >> n >> m;
vector <int> d(n); init();
for (int i = 0; i < n; i++){cin >> d[i]; d[i] *= d[i];}
sort(d.begin() , d.end());
for (int i = 0; i < maxn; i++) {
for (int j = 0; j < maxn; j++) {
int t = i * i + j * j; if (!t){continue;}
f[i][j] = n - (lower_bound(d.begin() , d.end() , t) - d.begin());
}
} f = inv(1 - f); int ans = f[maxn-1][maxn-1];
for (int i = 0; i < m; i++){cin >> X[i] >> Y[i];}
for (int i = 0; i < m; i++){ans = (ans - 1ll * dfs(i) * f[maxn-1-X[i]][maxn-1-Y[i]] % mod + mod) % mod;}
cout << ans << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1728ms
memory: 95232kb
input:
1 0 1
output:
472799582
result:
ok single line: '472799582'
Test #2:
score: 0
Accepted
time: 1709ms
memory: 95268kb
input:
1 1 1 500 500
output:
447362327
result:
ok single line: '447362327'
Test #3:
score: 0
Accepted
time: 1727ms
memory: 95304kb
input:
1 0 2
output:
277036758
result:
ok single line: '277036758'
Test #4:
score: -100
Wrong Answer
time: 1748ms
memory: 95220kb
input:
1 1 402 305 914
output:
124240326
result:
wrong answer 1st lines differ - expected: '902644270', found: '124240326'