zoukankan      html  css  js  c++  java
  • cf E. Thief in a Shop

    传送门
    其实是个假的多项式快速幂
    (n)种物品里,选择(k)个物品,然后看有几种权值和有哪些

    就是母函数模板吧,然后k次多项式乘法,而且是对于一个多项式来说,那就进行多项式快速幂。同时用fft维护,(真多项式快速幂应该不是这么简单)
    如果说用ntt的话,要用双膜去求,因为只取一个膜会被使得多项式的值变成0的。其实我感觉就不能取模,所以还是fft维护比较好

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    using namespace std;
    const int N = 3e6 + 5; // 刚好比n大的2的k次方再乘2
    struct Complex{
        double x, y;
        Complex(double x = 0, double y = 0):x(x),y(y){};
        inline Complex operator + (const Complex b) const {
            return Complex(x + b.x,y + b.y);
        }
        inline Complex operator - (const Complex b) const {
            return Complex(x - b.x,y - b.y);
        }
        inline Complex operator * (const Complex b) const {
            return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
        }
    };
    namespace FFT{
        const double Pi = acos(-1);
        const int N = 3e6 + 5; // 刚好比n大的2的k次方再乘2
        Complex F[N], G[N];
        int r[N], n, m;
        void FFT(Complex *a, int n, int inv){
            for(int i = 0; i < n; i++)
                if(r[i] > i) swap(a[r[i]], a[i]);
    
           for(int mid = 2; mid <= n; mid <<= 1){
                Complex x(cos(2 * Pi / mid), inv * sin(2 * Pi / mid));
                for(int i = 0; i < n; i += mid){
                    Complex w(1,0);
                    for(int j = i; j < i + (mid >> 1); j++, w = w * x){
                        Complex t1 = a[j],t2 = a[j + (mid >> 1)] * w;
                        a[j] = t1 + t2; a[j + (mid >> 1)] = t1 - t2;
                    }
                }
            }
        }
        void mul(int *a, int *b, int *c, int nn, int mm, int &k) {
            n = nn, m = mm;
            for(mm += nn, nn = 1; nn <= mm; nn *= 2);
            for(int i = 0; i <= nn; i++) F[i].x = F[i].y = G[i].x = G[i].y = 0;
            for(int i = 0; i <= n; i++) F[i].x = a[i];
            for(int i = 0; i <= m; i++) G[i].x = b[i];
            int l = 0;
            for(m += n, n = 1; n <= m; n *= 2, l++);
            for(int i = 0; i < n; i++)
                r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
            FFT(F, n, 1); FFT(G, n, 1);
            for(int i = 0; i < n; i++) F[i] = F[i] * G[i];
            FFT(F, n, -1);  k = m;
            for(int i = 0; i <= m; i++) {
                int x = int(F[i].x / n + 0.5);
                c[i] = x ? 1 : 0;
            }
        }
    }
    int a[N], b[N], ans[N];
    int quick(int *a, int n, int k) {
        ans[0] = 1; int nu1 = n, nu2 = n;
        for(int i = 0; i <= n; i++) b[i] = a[i];
        while(k){
            if(k & 1) FFT::mul(ans, a, ans, nu1, nu2, nu1);
            FFT::mul(a, a, a, nu2, nu2, nu2);
            k >>= 1;
        }
        for(int i = 0; i <= nu1; i++) a[i] = ans[i];
        return nu1;
    }
    int main(){
        int n, m = 0, k; 
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++) {
            int x; scanf("%d", &x);
            a[x] = 1;
            m = max(m, x);
        }
        int num = quick(a, m, k);
        for(int i = 0; i <= num; i++)
            if(a[i]) printf("%d ", i);
        return 0;
    }
    
  • 相关阅读:
    SqlServer Function 实例
    技术清单
    SQLSERVER 链接服务器执行存储过程
    SQLSERVER 链接服务器
    Oracle 新手语法记录
    MarkDown 语法备份
    C# WebAPI小记
    Rabbit MQ 学习 (二)
    Rabbit MQ 学习 (一)Window安装Erlang环境
    [vue2,nodejs,echarts,json]调查问卷
  • 原文地址:https://www.cnblogs.com/Emcikem/p/14247174.html
Copyright © 2011-2022 走看看