zoukankan      html  css  js  c++  java
  • [NOIP2014普及组T1]珠心算测验

    求数组有多少个数,恰好等于集合中另外两个(不同的)数之和?

    注意到数集比较小,而且涉及到下标的加法,可以很自然地想到卷积

    注意减去自己加自己的贡献

    真是一道NTT练手好题

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define Dollar1 998244353
    #define MAXN 70001
    #define int long long
    int lim, dig, rev[MAXN], n, sums[MAXN], A[MAXN];
    const int G = 3, Ginv = (Dollar1 + 1) / 3;
    void init(int sz) {
        lim = 1; dig = 0;
        while (lim <= sz << 1) lim <<= 1, ++dig;
        for (int i = 0; i != lim; ++i)
            rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (dig - 1));
    }
    inline int fastpow(int a, int b) {
        int res = 1;
        while (b) {
            if (b & 1) res = res * a % Dollar1;
            a = a * a % Dollar1;
            b >>= 1;
        }
        return res;
    }
    void NTT(int * A, int type) {
        for (int i = 0; i != lim; ++i)
            if (i < rev[i])
                swap(A[i], A[rev[i]]);
        for (int mid = 1; mid < lim; mid <<= 1) {
            int Wn = fastpow(type == 1 ? G : Ginv, (Dollar1 + 1) / mid / 2);
            for (int k = 0; k < lim; k += (mid << 1)) {
                int W = 1;
                for (int l = 0; l < mid; ++l, W = W * Wn % Dollar1) {
                    int X = A[l + k], Y = A[l + k + mid] * W % Dollar1;
                    A[l + k] = (X + Y) % Dollar1;
                    A[l + k + mid] = (X - Y + Dollar1) % Dollar1;
                }
            }
        }
        if (type == -1) {
            const int liminv = fastpow(lim, Dollar1 - 2);
            for (int i = 0; i != lim; ++i)
                A[i] = A[i] * liminv % Dollar1;
        }
    }
    signed main() {
        cin >> n;
        init(10000);
        for (int i = 1; i <= n; ++i) cin >> sums[i], A[sums[i]] = 1;
        NTT(A, 1);
        for (int i = 0; i != lim; ++i) (A[i] *= A[i]) %= Dollar1;
        NTT(A, -1);
        for (int i = 1; i <= n; ++i) --A[sums[i] << 1];
        int ans = 0;
        for (int i = 1; i <= n; ++i) ans += (bool)A[sums[i]];
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    Vue 服务器端渲染(一)
    vue笔记 介绍及安装 一
    Node.js 学习笔记 (一) 安装配置
    Java开发中的23种设计模式详解(转)
    spring-boot整合ehcache实现缓存机制
    STM32流水灯
    SD卡封转及管脚说明
    随笔分类
    函数的设计之我见
    让灵魂追得上我们疲惫的身体
  • 原文地址:https://www.cnblogs.com/daklqw/p/9463880.html
Copyright © 2011-2022 走看看