zoukankan      html  css  js  c++  java
  • 多项式汇总[巨常数]

    一个多月前写的板子,忘了放上来了,今天莫名其妙地想起来了

    包含多项式乘法,多项式求逆,多项式除法/取模,多项式exp,多项式ln,多项式求导,多项式积分等基本操作

    由于懒癌,这里直接开vector表示多项式,常数贼大(然后我把一机房人带坏了

    以后可能会写一个常数小的多项式板子

    #include <bits/stdc++.h>
    using namespace std;
    
    const int p = 998244353;
    
    int qpow(int x, int y)
    {
    	int res = 1;
    	while (y > 0)
    	{
    		if (y & 1)
    			res = 1LL * res * x % p;
    		x = 1LL * x * x % p;
    		y >>= 1;
    	}
    	return res;
    }
    
    void FNTT(vector<int> &A, int len, int flag)
    {
    	A.resize(len);
    	int *r = new int[len];
    	r[0] = 0;
    	for (int i = 0; i < len; i++)
    		r[i] = (r[i >> 1] >> 1) | ((i & 1) * (len >> 1));
    	for (int i = 0; i < len; i++)
    		if (i < r[i])
    			swap(A[i], A[r[i]]);
    	int gn, g, t, A0, A1;
    	for (int i = 1; i < len; i <<= 1)
    	{
    		gn = qpow(3, (p - 1) / (i * 2));
    		for (int j = 0; j < len; j += (i << 1))
    		{
    			g = 1;
    			A0 = j;
    			A1 = A0 + i;
    			for (int k = 0; k < i; k++, A0++, A1++, g = (1LL * g * gn) % p)
    			{
    				t = (1LL * A[A1] * g) % p;
    				A[A1] = ((A[A0] - t) % p + p) % p;
    				A[A0] = (A[A0] + t) % p;
    			}
    		}
    	}
    	if (flag == -1)
    	{
    		reverse(A.begin() + 1, A.end());
    		int inv = qpow(len, p - 2);
    		for (int i = 0; i < len; i++)
    			A[i] = 1LL * A[i] * inv % p;
    	}
    	delete []r;
    }
    
    vector<int> operator+(vector<int> a, vector<int> b)
    {
    	vector<int> res;
    	res.resize(max(a.size(), b.size()));
    	a.resize(res.size());
    	b.resize(res.size());
    	for (int i = 0; i < (int)res.size(); i++)
    		res[i] = (a[i] + b[i]) % p;
    	return res;
    }
    
    vector<int> operator-(vector<int> a, vector<int> b)
    {
    	vector<int> res;
    	res.resize(max(a.size(), b.size()));
    	a.resize(res.size());
    	b.resize(res.size());
    	for (int i = 0; i < (int)res.size(); i++)
    		res[i] = ((a[i] - b[i]) % p + p) % p;
    	return res;
    }
    
    vector<int> operator*(vector<int> a, vector<int> b)
    {
    	int len = 1;
    	int sz = a.size() + b.size() - 1;
    	while (len <= sz) len <<= 1;
    	FNTT(a, len, 1);
    	FNTT(b, len, 1);
    	vector<int> res;
    	res.resize(len);
    	for (int i = 0; i < len; i++)
    		res[i] = 1LL * a[i] * b[i] % p;
    	FNTT(res, len, -1);
    	res.resize(sz);
    	return res;
    }
    
    vector<int> poly_inv(vector<int> a)
    {
    	if (a.size() == 1)
    	{
    		a[0] = qpow(a[0], p - 2);
    		return a;
    	}
    	int n = a.size(), newsz = (n + 1) >> 1;
    	vector<int> b(a);
    	b.resize(newsz);
    	b = poly_inv(b);
    	int len = 1;
    	while (len <= (n << 1)) len <<= 1;
    	vector<int> c(a);
    	FNTT(a, len, 1);
    	FNTT(b, len, 1);
    	for (int i = 0; i < len; i++)
    		a[i] = ((1LL * b[i] * (2 - 1LL * a[i] * b[i] % p)) % p + p) % p;
    	FNTT(a, len, -1);
    	a.resize(n);
    	return a;
    }
    
    vector<int> intergal(vector<int> a)
    {
    	int sz = a.size();
    	a.resize(sz + 1);
    	for (int i = sz; i >= 1; i--)
    		a[i] = 1LL * a[i - 1] * qpow(i, p - 2) % p;
    	a[0] = 0;
    	return a;
    }
    
    vector<int> derivation(vector<int> a)
    {
    	int sz = a.size();
    	for (int i = 1; i < sz; i++)
    		a[i - 1] = 1LL * a[i] * i % p;
    	a.resize(sz - 1);
    	return a;
    }
    
    vector<int> ln(vector<int> a)
    {
    	return intergal(derivation(a) * poly_inv(a));
    }
    
    vector<int> poly_r(vector<int> a)
    {
    	reverse(a.begin(), a.end());
    	return a;
    }
    
    void div(vector<int> f, vector<int> g, vector<int> &q, vector<int> &r)
    {
    	int n = f.size() - 1, m = g.size() - 1;
    	vector<int> gr = poly_r(g);
    	gr.resize(n - m + 1);
    	q = poly_r(f) * poly_inv(gr);
    	q.resize(n - m + 1);
    	q = poly_r(q);
    	vector<int> gq = g * q;
    	r.resize(m);
    	gq.resize(m);
    	f.resize(m);
    	for (int i = 0; i < m; i++)
    		r[i] = ((f[i] - gq[i]) % p + p) % p;
    }
    
    vector<int> poly_exp(vector<int> a)
    {
    	if (a.size() == 1)
    	{
    		a[0]++;
    		return a;
    	}
    	vector<int> f0 = a;
    	f0.resize((a.size() + 1) / 2);
    	f0 = poly_exp(f0);
    	vector<int> f;
    	a[0]++;
    	f = (a - ln(f0));
    	f = f0 * f;
    	f.resize(a.size());
    	return f;
    }
    
    int main_luogu3803()
    {
    	vector<int> a, b;
    	int n, m;
    	scanf("%d%d", &n, &m);
    	a.resize(n + 1);
    	b.resize(m + 1);
    	for (int i = 0; i <= n; i++)
    		scanf("%d", &a[i]);
    	for (int i = 0; i <= m; i++)
    		scanf("%d", &b[i]);
    	vector<int> res = a * b;
    	for (int i = 0; i <= n + m; i++)
    		printf("%d%c", res[i], i == n + m ? '
    ' : ' ');
    	return 0;
    }
    
    int main_luogu4238()
    {
    	vector<int> a;
    	int n;
    	scanf("%d", &n);
    	a.resize(n);
    	for (int i = 0; i < n; i++)
    		scanf("%d", &a[i]);
    	a = poly_inv(a);
    	for (int i = 0; i < n; i++)
    		printf("%d%c", a[i], i == n - 1 ? '
    ' : ' ');
    	return 0;
    }
    
    int main_luogu4725()
    {
    	vector<int> a;
    	int n;
    	scanf("%d", &n);
    	a.resize(n);
    	for (int i = 0; i < n; i++)
    		scanf("%d", &a[i]);
    	a = ln(a);
    	for (int i = 0; i < n; i++)
    		printf("%d%c", a[i], i == n - 1 ? '
    ' : ' ');
    	return 0;
    }
    
    int main_luogu4512()
    {
    	vector<int> f, g;
    	int n, m;
    	scanf("%d%d", &n, &m);
    	f.resize(n + 1);
    	g.resize(m + 1);
    	for (int i = 0; i <= n; i++)
    		scanf("%d", &f[i]);
    	for (int i = 0; i <= m; i++)
    		scanf("%d", &g[i]);
    	vector<int> q, r;
    	div(f, g, q, r);
    	for (int i = 0; i <= n - m; i++)
    		printf("%d%c", q[i], i == n - m ? '
    ' : ' ');
    	for (int i = 0; i < m; i++)
    		printf("%d%c", r[i], i == m - 1 ? '
    ' : ' ');
    	return 0;
    }
    
    int main_luogu4726()
    {
    	vector<int> a;
    	int n;
    	scanf("%d", &n);
    	a.resize(n * 2);
    	for (int i = 0; i < n; i++)
    		scanf("%d", &a[i]);
    	a = poly_exp(a);
    	for (int i = 0; i < n; i++)
    		printf("%d%c", a[i], i == n - 1 ? '
    ' : ' ');
    	return 0;
    }
    
    
    int main()
    {
    	main_luogu4726();
    	return 0;
    }
    
  • 相关阅读:
    郁闷的出纳员 平衡二叉树(SBT)
    POJ 3225 Help with Intervals (线段树,区间成段更新)
    HDU 3038 How Many Answers Are Wrong (并查集)
    POJ 1733 Parity game (HASH+并查集)
    POJ 1417 True Liars(并查集+DP)
    POJ 2912 Rochambeau(枚举+并查集)
    UILabel添加发光效果
    TinyMCE integration with phpBB3
    快速重传与快速恢复算法
    TCP的超时与重传
  • 原文地址:https://www.cnblogs.com/oier/p/10284702.html
Copyright © 2011-2022 走看看