QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#431850#8312. Fly Me To The MoonSlongodWA 1748ms95304kbC++1710.1kb2024-06-06 10:47:412024-06-06 10:47:42

Judging History

你现在查看的是最新测评结果

  • [2024-06-06 10:47:42]
  • 评测
  • 测评结果:WA
  • 用时:1748ms
  • 内存:95304kb
  • [2024-06-06 10:47:41]
  • 提交

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'