首页 > 其他分享 >洛谷 P5488 差分与前缀和

洛谷 P5488 差分与前缀和

时间:2023-05-11 19:11:26浏览次数:53  
标签:typedef le 洛谷 P5488 int ll 差分 long define

洛谷传送门

看起来很毒瘤,但是推出贡献系数后就是一个朴素的卷积了。

首先考虑前缀和。考虑 \(j\ (j \le i)\) 的 \(a_j\) 贡献到 \(i\) 的过程,是找到 \(j = p_0 \le p_1 \le \cdots \le p_k = i\) 的方案数。令 \(x_i = p_i - p_{i-1}\),即求 \(x_i \ge 0, \sum\limits_{i=1}^k x_i = i - j\) 的方案数。运用插板法易得方案数为 \(\binom{i-j+k-1}{k-1}\)。

设 \(b_i = \binom{i+k-1}{k-1}\),那么 \(b_0 = 1, b_i = b_{i-1} \times \frac{i+k-1}{i}\)。

那么 \(s_i = \sum\limits_{j=1}^i a_j b_{i-j}\),直接乘法卷积即可。

然后考虑差分。考虑 \(j (j \le i)\) 的 \(a_j\) 贡献到 \(i\) 的过程,是找到 \(j = p_0 \le p_1 \le \cdots \le p_k = i\) 且 \(p_i - p_{i-1} \le 1\) 的方案数。令 \(x_i = p_i - p_{i-1}\),即求 \(x_i \in \{0, 1\}, \sum\limits_{i=1}^k x_i = i - j\) 的方案数。相当于从 \(k\) 个变量中选出 \(i - j\) 个赋值为 \(1\),方案数为 \(\binom{k}{i-j}\);同时因为向左一步要取相反数,所以最后的贡献系数为 \((-1)^{i-j} \binom{k}{i-j}\)。

设 \(b_i = (-1)^i \binom{k}{i}\),那么 \(b_0 = 1, b_i = -\frac{(k+1-i)b_{i-1}}{i}\)。

那么 \(s_i = \sum\limits_{j=1}^i a_j b_{i-j}\),直接乘法卷积即可。

注意到如果 \(k > 1004535809\),因为有第 \(1004535809\) 次的存在,所以之后不会再产生贡献。因此 \(k\) 直接对 \(1004535809\) 取模即可。

code
// Problem: P5488 差分与前缀和
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P5488
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 300000;
const ll mod = 1004535809, G = 3;

inline ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline ll read() {
    char c = getchar();
    ll x = 0;
    for (; !isdigit(c); c = getchar()) ;
    for (; isdigit(c); c = getchar()) x = (x * 10 + (c ^ 48)) % mod;
    return x;
}

ll n, m, t, a[maxn], b[maxn], r[maxn];

typedef vector<ll> poly;

inline poly NTT(poly a, int op) {
	int n = (int)a.size();
	for (int i = 0; i < n; ++i) {
		if (i < r[i]) {
			swap(a[i], a[r[i]]);
		}
	}
	for (int k = 1; k < n; k <<= 1) {
		ll wn = qpow(op == 1 ? G : qpow(G, mod - 2), (mod - 1) / (k << 1));
		for (int i = 0; i < n; i += (k << 1)) {
			ll w = 1;
			for (int j = 0; j < k; ++j, w = w * wn % mod) {
				ll x = a[i + j], y = w * a[i + j + k] % mod;
				a[i + j] = (x + y) % mod;
				a[i + j + k] = (x - y + mod) % mod;
			}
		}
	}
	return a;
}

inline poly operator * (poly a, poly b) {
	a = NTT(a, 1);
	b = NTT(b, 1);
	int n = (int)a.size();
	for (int i = 0; i < n; ++i) {
		a[i] = a[i] * b[i] % mod;
	}
	a = NTT(a, -1);
	ll inv = qpow(n, mod - 2);
	for (int i = 0; i < n; ++i) {
		a[i] = a[i] * inv % mod;
	}
	return a;
}

void solve() {
	n = read();
	m = read();
	t = read();
	for (int i = 1; i <= n; ++i) {
		a[i] = read();
	}
	int k = 0;
	while ((1 << k) <= n * 2) {
		++k;
	}
	for (int i = 1; i < (1 << k); ++i) {
		r[i] = (r[i >> 1] >> 1) | ((i & 1) << (k - 1));
	}
	b[0] = 1;
	if (!t) {
		for (int i = 1; i <= n; ++i) {
			b[i] = b[i - 1] * (i + m - 1) % mod * qpow(i, mod - 2) % mod;
		}
	} else {
		for (int i = 1; i <= n; ++i) {
			b[i] = (i <= m ? (mod - (m + 1 - i) * qpow(i, mod - 2) % mod * b[i - 1] % mod) % mod : 0);
		}
	}
	poly A, B;
	for (int i = 0; i < (1 << k); ++i) {
		A.pb(a[i]);
		B.pb(b[i]);
	}
	poly C = A * B;
	for (int i = 1; i <= n; ++i) {
		printf("%lld ", C[i]);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,le,洛谷,P5488,int,ll,差分,long,define
From: https://www.cnblogs.com/zltzlt-blog/p/17391956.html

相关文章

  • 洛谷 P3321 [SDOI2015] 序列统计
    洛谷传送门感觉挺综合的一道题。考虑朴素dp,\(\forallx\inS,f_{i+1,jx\bmodm}\getsf_{i,j}\)。复杂度\(O(nm^2)\)。显然可以矩乘优化至\(O(m^3\logn)\),但是不能通过。如果转移式中是加法而不是乘法,那很容易卷积优化。接下来是一个很重要的套路:化乘为加。实数......
  • 洛谷 P8492 - [IOI2022] 无线电信号塔
    想到将最优化问题转化为数点问题的一步了,但是因为转化的姿势不太好导致我的数点不太能用特别简洁的数据结构维护,最后只好看题解(考虑先解决单组询问的问题,对于每个点\(i\),我们找出它左边最近的\(h_l\leh_i-D\)的点\(l\),和它右边最近的\(h_r\leh_i-D\)的点\(r\),然后新建一......
  • 洛谷 P8367 - [LNOI2022] 盒(组合数学)
    设\(a\)数组的前缀和为\(s_i\),\(b\)数组的前缀和为\(t_i\),那么根据模拟费用流或者贪心的思想,每一条边经过的次数即为\(|s_i-t_i|\),因此非常trivial的做法是转换贡献体,枚举每种方案下每条边被经过的次数,然后乘以\(w_i\)求和,具体来说:\[ans=\sum\limits_{i=1}^{n-1}\sum\l......
  • FFT 精度误差分析
    可能写的有错的,也可能没有,大家看着当个乐子就好。FFT是oi中常用的一种算法,但是我们没有关心过它的精度,所以我们现在来关心一下。我们知道对于一个长度为\(n\)的向量\(\alpha\),我们对它做DFT,相当于左乘了一个正交矩阵\(T\)(我们知道常规的DFT中做的不是标准的正交变换,但......
  • USART-CH32FV1x_2x_V3x--串口波特率误差分析及计算
    串口通讯波特率出现误差的因素串口通讯是一种异步通讯,收发双方需要按照约定的波特率进行通讯。当波特率出现误差时,在一些高精度要求场所可能会导致通讯出错。那导致波特率出现误差的因素都有哪些呢,今天就来分析一下。1.分频误差 首先,波特率是根据系统时钟分频产生的,而系统时......
  • 差分约束学习笔记
    2023.5.6写的太烂了重新写差分约束系统定义差分约束系统是一种特殊的\(n\)元一次不等式组,它包含\(n\)个变量\(x_{1},x_{2},...,x_{n}\)以及\(m\)个约束条件,每一个约束条件都是两个其中的变量做差构成的,形如\(x_{i}-x_{j}\lec_{k}\),其中\(1\lei,j\len,i\nej,1\l......
  • 洛谷 P3369 【模板】普通平衡树
    有旋Treap模板#include<bits/stdc++.h>usingnamespacestd;structNode{ Node*ch[2]; intval,rank; intrep_cnt; intsiz; Node(intval):val(val),rep_cnt(1),siz(1){ ch[0]=ch[1]=nullptr; rank=rand(); } voidupd_siz(){ siz=......
  • 洛谷P4824题解
    题面题意:给出字符串s和t,每次操作将s中出现的第一个t删去,直到不能删为止。求最后的串。|s|<=1e6题解:hash做法。(此题也有kmp和权值线段树做法)因为涉及到删除操作,所以我们要动态的实现这个过程。所以考虑开一个栈来存储当前留下的字符。然后每有一个字符入栈,就拿当前......
  • 洛谷P7469题解
    题面题意:有两个字符串a和b,问b中有多少个本质不同子串可以由a删除若干个字符得到。|a|,|b|<=3000题解:字典树(这个题做法很多,后补)。把字符串b的每个子串打到字典树上。然后因为3000^2*26这个东西比较大,所以不能用nxt[id][26]来存储,于是使用链式前向星存图,这样tri......
  • m基于整数序列的QC-LDPC的稀疏校验矩阵构造算法性能对比matlab仿真,对比差分序列,PEG,
    1.算法仿真效果matlab2013b仿真结果如下:  2.算法涉及理论知识概要       QC-LDPC(Quasi-CyslicLow-DensityParity-CheckCodes)即准循环LDPC码。之前介绍的LDPC码基本属于随机构造法,构造出的码性能很好,但校验矩阵具有不规律性,存在校验矩阵存储于读取困难、编码复......