COGS 2189 帕秋莉的超级多项式

放模板啦!

以后打比赛的时候直接复制过来。

说句实话vector的效率真的不怎么样,但是似乎也还行,最主要是……写得比较爽。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
typedef vector <ll> poly;

namespace Poly {
    const int L = 1 << 20;
    const ll P = 998244353LL;

    int lim, pos[L];

    inline ll fpow(ll x, ll y) {
        ll res = 1;
        for (; y > 0; y >>= 1) {
            if (y & 1) res = res * x % P;
            x = x * x % P;
        }
        return res;
    }

    const ll inv2 = fpow(2, P - 2);

    template <typename T>
    inline void inc(T &x, T y) {
        x += y;
        if (x >= P) x -= P;
    }

    template <typename T>
    inline void sub(T &x, T y) {
        x -= y;
        if (x < 0) x += P;
    }

    inline void prework(int len) {
        int l = 0;
        for (lim = 1; lim < len; lim <<= 1, ++l);
        for (int i = 0; i < lim; i++)
            pos[i] = (pos[i >> 1] >> 1) | ((i & 1) << (l - 1));
    }

    inline void ntt(poly &c, int opt) {
        c.resize(lim, 0);
        for (int i = 0; i < lim; i++)
            if (i < pos[i]) swap(c[i], c[pos[i]]);
        for (int i = 1; i < lim; i <<= 1) {
            ll wn = fpow(3, (P - 1) / (i << 1));
            if (opt == -1) wn = fpow(wn, P - 2);
            for (int len = i << 1, j = 0; j < lim; j += len) {
                ll w = 1;
                for (int k = 0; k < i; k++, w = w * wn % P) {
                    ll x = c[j + k], y = w * c[j + k + i] % P;
                    c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;
                }
            }
        }

        if (opt == -1) {
            ll inv = fpow(lim, P - 2);
            for (int i = 0; i < lim; i++) c[i] = c[i] * inv % P;
        }
    }

    inline poly operator * (const poly &x, const poly &y) {
        poly res, u = x, v = y;
        prework(u.size() + v.size() - 1);
        ntt(u, 1), ntt(v, 1);
        for (int i = 0; i < lim; i++) res.push_back(v[i] * u[i] % P);
        ntt(res, -1);
        res.resize(u.size() + v.size() - 1);
        return res;
    }

    poly getInv(poly x, int len) {
        x.resize(len);
        if (len == 1) {
            poly res;
            res.push_back(fpow(x[0], P - 2));
            return res;
        }
        poly y = getInv(x, (len + 1) >> 1);
        prework(len << 1);

        poly u = x, v = y, res;
        ntt(u, 1), ntt(v, 1);
        for (int i = 0; i < lim; i++) res.push_back(v[i] * (2LL - u[i] * v[i] % P + P) % P);
        ntt(res, -1);

        res.resize(len);
        return res;
    }

    inline void direv(poly &c) {
        for (int i = 0; i < (int)c.size() - 1; i++)
            c[i] = c[i + 1] * (i + 1) % P;
        c[c.size() - 1] = 0;
    }

    inline void integ(poly &c) {
        for (int i = (int)c.size() - 1; i > 0; i--)
            c[i] = c[i - 1] * fpow(i, P - 2) % P;
        c[0] = 0;
    }

    inline poly getLn(poly c) {
        poly a = getInv(c, (int)c.size());
        poly b = c;
        direv(b);

        poly res = b * a;
        res.resize(c.size());
        integ(res);
        return res;
    }

    poly getSqrt(poly x, int len) {
        x.resize(len);
        if (len == 1) {
            poly res;
            res.push_back(sqrt(x[0]));
            return res;
        }
        poly y = getSqrt(x, (len + 1) >> 1);
        poly u = x, v = y, w, res;
        w = getInv(y, len);

        prework(len << 1);
        ntt(u, 1), ntt(v, 1), ntt(w, 1);
        for (int i = 0; i < lim; i++)
            res.push_back((v[i] * v[i] % P + u[i]) % P * w[i] % P * inv2 % P);
        ntt(res, -1);
        res.resize(len);

        return res;
    }

    poly getExp(poly x, int len) {
        x.resize(len, 0);
        if (len == 1) {
            poly res;
            res.push_back(1);
            return res;
        }

        poly y = getExp(x, (len + 1) >> 1);
        poly u = x, v = y, w = y, res;
        w.resize(len, 0);
        w = getLn(w);

        prework(len << 1);
        u[0] = (u[0] + 1 - w[0] + P) % P;
        for (int i = 1; i < (int)u.size(); i++) u[i] = (u[i] - w[i] + P) % P;

        ntt(u, 1), ntt(v, 1);
        for (int i = 0; i < lim; i++) res.push_back(u[i] * v[i] % P);
        ntt(res, -1);

        res.resize(len);
        return res;
    }

    inline poly fpow(poly x, ll y, int n) {
        x = getLn(x);
        for (int i = 0; i < n; i++) x[i] = x[i] * y % P;
        x = getExp(x, n);
        return x;
    }

}

template <typename T>
inline void read(T &X) {
    X = 0; char ch = 0; T op = 1;
    for (; ch > ‘9‘|| ch < ‘0‘; ch = getchar())
        if (ch == ‘-‘) op = -1;
    for (; ch >= ‘0‘ && ch <= ‘9‘; ch = getchar())
        X = (X << 3) + (X << 1) + ch - 48;
    X *= op;
}

int main() {
//    freopen("Sample.txt", "r", stdin);
    freopen("polynomial.in", "r", stdin);
    freopen("polynomial.out", "w", stdout);

    int n, k;
    read(n), read(k);
    poly a; a.resize(n);
    for (int i = 0; i < n; i++) read(a[i]);

    a = Poly :: getSqrt(a, n);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);    */

    a = Poly :: getInv(a, n);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);   */

    Poly :: integ(a);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);   */

    a = Poly :: getExp(a, n);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);   */

    a = Poly :: getInv(a, n);
    Poly :: inc(a[0], 1LL);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);    */

    a = Poly :: getLn(a);
    Poly :: inc(a[0], 1LL);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);    */

    a = Poly :: fpow(a, k, n);

/*    for (int i = 0; i < n; i++)
        printf("%I64d%c", a[i], " \n"[i == n - 1]);    */

    Poly :: direv(a);

    for (int i = 0; i < n; i++)
        printf("%lld%c", a[i], " \n"[i == n - 1]);
    return 0;
} 

原文地址:https://www.cnblogs.com/CzxingcHen/p/10358153.html

时间: 2024-11-08 21:05:08

COGS 2189 帕秋莉的超级多项式的相关文章

【Codevs 1376】帕秋莉?诺蕾姬

http://codevs.cn/problem/1376/ 枚举修改哪两位,将sum减去之前位置的数+交换之后  %m==0即可 预处理26的次方+O(n^2) // <1376.cpp> - Tue Oct 18 21:50:03 2016 // This file is made by YJinpeng,created by XuYike's black technology automatically. // Copyright (C) 2016 ChangJun High Schoo

【题解】Luogu P4910 帕秋莉的手环

原题传送门 "连续的两个中至少有1个金的"珂以理解为"不能有两个木相连" 我们考虑一个一个将元素加入手环 设f\([i][0/1]\)表示长度为\(i\)手环末尾有\(0/1\)个木的种类数 仔细想想发现它实际就是一个斐波那契数列(\(fib[1]=fib[2]=1\)) 因为首尾相接,所以开头要分类讨论 第一个是金:对答案的贡献为\(fib[n]+fib[n-1]\) 第一个是木:对答案的贡献为\(fib[n-1]\) 矩阵快速幂即可 #include <b

多项式求ln,求exp,开方,快速幂 学习总结

按理说Po姐姐三月份来讲课的时候我就应该学了 但是当时觉得比较难加上自己比较懒,所以就QAQ了 现在不得不重新弄一遍了 首先说多项式求ln 设G(x)=lnF(x) 我们两边求导可以得到G'(x)=F‘(x)/F(x) 则G(x)就是F’(x)/F(x)的积分 我们知道多项式求导和积分是O(n)的,多项式求逆是O(nlogn)的 所以总时间复杂度O(nlogn) 多项式求ln一般解决的问题是这样的 设多项式f表示一些奇怪的东西,由一些奇怪的东西有序组成的方案为 f^1+f^2+f^3…… 化简之

【全家福】多项式的各种板子

写完帕秋莉的超级多项式于是正好贴个模板大汇总(带优化的那种...) //by Judge #include<bits/stdc++.h> #define Rg register #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i) #define ll long long using namespace std; const in

对于有关东方的题目的整理。。

东方赛高 此为总贴 收录以东方project为背景的题目. 1. luogu P3345 [ZJOI2015]幻想乡战略游戏 动态点分治(暴力水过) 2. luogu P3344 [ZJOI2015]幻想乡WIFI搭建计划 3. luogu P3343 [ZJOI2015]地震后的幻想乡 4. luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 5. luogu P3347 [ZJOI2015]醉熏熏的幻想乡 6. luogu P1726 上白泽慧音 求强连通分量, 输出最大强连通分量

哲学の舍

本格的哲♂学作品:   王の演讲 http://www.bilibili.com/video/av613605/ VAN様kink访谈编 http://www.bilibili.com/video/av451462/ VAN様 访谈篇[修复] http://www.bilibili.com/video/av382422/ 本格的嘎七姆七胖次摔跤 兄贵VS木吉 http://www.bilibili.com/video/av458939/ 本格的嘎七姆七胖次摔跤 比奥VSVAN http://ww

2803 爱丽丝&#183;玛格特罗依德

2803 爱丽丝·玛格特罗依德 时间限制: 4 s 空间限制: 8000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 在幻想乡中,爱丽丝·玛格特罗依德是一名居住在魔法森林的魔法使,擅长 召唤人偶.一天她的“机油”帕秋莉找到了她,要他防御雾雨魔理沙对巴瓦卢魔 法图书馆的“破坏”.她有n点魔法值,每召唤出一个『上海人形』就要消耗若干点(x),最后, 它们造成的威力就是每个人形所消耗的魔法值的总积.她为了知道能有多少威力,找到了全幻想乡唯一会编程的你,你不

&lt;东方梦符祭&gt; N2无尽40波通关

先上图吧 阵容:纯粹 + 伪魔法队 主C:神妈 露米娅(我觉得不厉害了) 灵梦 控制:琪露诺 + 蕾蒂 永江依玖(听说很厉害 没培育满 没看到效果) 挂件:铃仙挂机 帕秋莉 大妖精(链神妈) 圣今天才出的前50波还行也不知道厉害不厉害 起手双白 老鼠 12波才来秋香子 23波五星鼠 装备还抽的挺齐的 四把太阳伞没用上 露米娅四阴阳玉输出赶不上神妈的一半(难道是没放前面吗) 毕竟是R卡呀 40波的时候有点迷茫 只有露米娅和灵梦 感觉纯粹输出不够 不知道走魔法还是物理 还好选择了神妈 太强辣 要是不

国庆50年

自传58.在佳木斯市委党校十五----话住烧穿 一九九九年九月我在佳木斯市委党校经济学教研室工作十五学年.钰香妻在市委党校教务处评省先进函授工作者小女儿正联系上班. 大女儿在第五中学升任语文高级教师女婿在发电厂工作成绩优秀.儿子在市建行工作儿媳在市农行工作小孙女五岁半近期住在大连. 九月开学人们就议论暑假见闻外批李登辉内批李***等畅所欲言.九月六日后我讲市场经济运行学60学时汤原党校经管大专班10天.九月十六日后我讲扩大内需开拓市场8学时市党校县处班和中青班. 九月十七日我讲跨世纪农业基础地位