这个柿子挺别致的......还有信仰膜数998244353


直接讲正解吧......

首先发现这个柿子从上往下算好像不怎么行,我们从下往上看,(下面令\(Ans_r = sum_{k,1,r}\))。

考虑\(a_i\)对\(Ans_r\)的贡献(\(1 \le i \le r\)),即\(a_i\)在\(sum_{k,1,r}\)中被算了多少次,我们假设\(a_i\)被算了\(c_i\)次。答案就是\(Ans_r = \sum\limits_{i = 1} ^ r a_i c_i\) 废话。

这个\(c_i\)显然是位置\(i\)在\([1,r]\)中被\(k-1\)重区间覆盖的方案数。

逼格高一点就是选\(k-1\)个(减一是因为最大的区间已经定下来是\([1,r]\)了)区间\([l_1,r_1],[l_2,r_2],\cdots,[l_{k-1},r_{k-1}]\),使得\(1 \le l_i,r_i \le r,[l_i, r_i] \subset [l_{i+1}, r_{i+1}]\)且\(l_1 \le i \le r_1\)的方案数。

这个就是在\(1...i\)选\(k-1\)个位置(可重复)的方案数\(\times\)在\(i...r\)里选\(k-1\)个位置(可重复)的方案数。

有\(c_i = s(i,k-1) s(r-i+1,k-1)\),其中\(s(n,m)\)表示在一个有\(n\)种元素,每种元素有无限个的集合内选\(m\)个元素出来做组合的方案数。

下面我们来推\(s\)。

我们手里有一个有\(n\)个元素的集合,且每种元素有无限个。

实际上\(s(n,m)\)就等价于\(x_1 + x_2 + \cdots + x_n = m\)的非负整数解的个数,\(x_i\)表示第\(i\)种元素选了多少个。

经典的隔板法吧。这个好像小学奥数就有......

他就等价于这个集合的全排个数

\[T = \{ m \cdot 1, (n-1) \cdot \text{|} \}
\]

可以理解为把\(m\)个\(1\)用\((n-1)\)个板子隔开来,那么相邻两个板子之间,以及左右两边就代表了一个$x_1...x_n $

即\(s(n,m) = \frac{(m+n-1)!}{m!(n-1)!} = \binom{n+m-1}{m}\)

那么\(c_i = \binom{i + k-2}{k-1}\binom{r-i+k-1}{k-1}\)

写回\(Ans_r\)就是

\[Ans_r = \sum\limits_{i = 1}^{r} a_ic_i = \sum\limits_{i = 1} ^ r a_i \binom{i + k - 2}{k-1}\binom{r-i+k-1}{k-1}
\]

这个柿子非常卷积吧!

我们令\(g_i = \binom{i + k - 1}{k - 1}\),\(f_i = \binom{i + k - 2}{k-1}a_i\),那么

\[Ans_r = \sum\limits_{i = 1} ^ r f_ig_{r-i}
\]

因为有信仰质数\(998244353\),\(NTT\)一下就没了。

还有由于\(k\)很大,我们可以递推出\(g\),然后用\(f_i = a_i g_{i-1}\)来算\(f\)。

#include <bits/stdc++.h>
using namespace std;
const int N=3e5+10,P=998244353,G=3,IG=(P+1)/G;
inline int fpow(int a,int b){
int ret=1; for (;b;b>>=1,a=1ll*a*a%P)
if (b&1) ret=1ll*a*ret%P;
return ret;
}
inline int add(int x,int y){return x+y>=P?x+y-P:x+y;}
inline int sub(int x,int y){return x-y<0?x-y+P:x-y;}
int rev[N];
void init(int limit){
for (int i=0;i<limit;i++)rev[i]=rev[i>>1]>>1|((i&1)?limit>>1:0);
}
void ntt(int *f,int n,int flg){
for (int i=0;i<n;i++) if (rev[i]<i)swap(f[i],f[rev[i]]);
for (int len=2,k=1;len<=n;len<<=1,k<<=1){
int wn=fpow(flg==1?G:IG,(P-1)/len);
for (int i=0;i<n;i+=len){
for (int w=1,j=i;j<i+k;j++,w=1ll*w*wn%P){
int tmp=1ll*w*f[j+k]%P;
f[j+k]=sub(f[j],tmp),f[j]=add(f[j],tmp);
}
}
}
if (flg==-1){
int inv=fpow(n,P-2);
for (int i=0;i<n;i++)f[i]=1ll*f[i]*inv%P;
}
}
int f[N],g[N],a[N],inv[N];
int main(){
int n,k; scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)scanf("%d",&a[i]);
inv[1]=1; for (int i=2;i<=n;i++) inv[i]=1ll*inv[P%i]*(P-P/i)%P; // 线性推逆元
g[0]=1,g[1]=k%P; for (int i=2;i<=n;i++)
g[i]=1ll*g[i-1]*inv[i]%P*(i+k-1)%P; // 颓g
for (int i=1;i<=n;i++) f[i]=1ll*a[i]*g[i-1]%P; // 颓f
int limit=1; while(limit<=n*2)limit<<=1; init(limit);
ntt(f,limit,1),ntt(g,limit,1);
for (int i=0;i<limit;i++) f[i]=1ll*f[i]*g[i]%P;
ntt(f,limit,-1);
for (int i=1;i<=n;i++) printf("%d ",f[i]);
return 0;
}

[题解] Luogu P5641 【CSGRound2】开拓者的卓识的更多相关文章

  1. [题解] Luogu P5446 [THUPC2018]绿绿和串串

    [题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,..., ...

  2. 题解 Luogu P2499: [SDOI2012]象棋

    关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可 ...

  3. 题解 luogu P1144 【最短路计数】

    本蒟蒻也来发一次题解第一篇请见谅 这个题有几个要点 1.无向无权图,建图的时候别忘记建来回的有向边[因此WA掉1次 2.无权嘛,那么边长建成1就好了2333333 3.最短路采用迪杰斯特拉(别忘用堆优 ...

  4. 题解 Luogu P1110 【[ZJOI2007]报表统计】

    感谢 @cmy962085349 提供的hack数据,已经改对了. 先声明,我好像是题解里写双$fhq$ $treap$里唯一能过的...(最后两个点啊) 思路:首先看题目,$MIN_GAP_SORT ...

  5. 题解 Luogu P3370

    讲讲这题的几种做法: 暴力匹配法 rt,暴力匹配,即把字符串存起来一位一位判相等 时间复杂度$ O(n^2·m) $ 再看看数据范围 \(n\le10^5,m\le10^3\) 当场爆炸.当然有暴力分 ...

  6. 题解 Luogu P3623 [APIO2008]免费道路

    [APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可 ...

  7. [题解]luogu P4116 Qtree3

    终于来到了Qtree3, 其实这是Qtree系列中最简单的一道题,并不需要线段树, 只要树链剖分的一点思想就吼了. 对于树链剖分剖出来的每一根重链,在重链上维护一个Set就好了, 每一个Set里存的都 ...

  8. 题解 Luogu P3959 【宝藏】

    来一篇不那么慢的状压??? 话说这题根本没有紫题难度吧,数据还那么水 我是不会告诉你我被hack了 一看数据规模,n≤12,果断状压. 然后起点要枚举,就设dp状态: f[i][j]=以i为起点到j状 ...

  9. 题解 Luogu P1099 【树网的核】

    这题是真的水啊... ------------ 昨天模拟赛考了这题,很多人都是O($n^3$)水过,但我认为,要做就做的足够好(其实是我根本没想到O($n^3$)的做法),然后就开始想O(n)的解法. ...

随机推荐

  1. navcat工具常用快捷键

     navcat工具常用快捷键 ctrl + n: 打开新查询窗口 ctrl + shit + r: 只运行选中的语句 ctrl + /: 注释 (选中要注释的行,然后用快捷键注释) ctrl + sh ...

  2. OpenJ_Bailian - 1088 滑雪(记忆化搜索)

    题意:给定一个二维数组,一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小,输出可以滑行的最长区域的长度. 分析:对于每一个点,进行记忆化搜索.若某点可以向四周某几个点滑行,记忆化搜索求出 ...

  3. OS、浏览器排名:Win10狂飙、Chrome逆天

    根据 Netmarketshare公布的最新数据,2019年7月,Windows 10系统市场份额获得显著增长,市场份额创下新高:Windows 7则进一步衰退,份额下滑高达3.6%,这也是其历史上最 ...

  4. Easy_Re

    这题比较简单,一波常规的操作之后直接上ida(小白的常规操作在以前的博客里都有所以这里不在赘述了),ida打开之后查看一下, 这里应该就是一个入口点了,接着搜索flag字符串, 上面的黄色的部分转换成 ...

  5. 小程序包大小超过2M的解决方法

    小程序的包被限制在2M以下, 超出的时候点击预览, 发现报错: Error: 代码包大小为 3701 kb,上限为 2048 kb,请删除文件后重试 1. 优化代码, 删除掉不用的代码 2. 图片压缩 ...

  6. oracle根据一张表更新另外一张表

    知道是两张表进行更新,之前作过mysql的,直接就写了: update a,b set a.code = b.code wehre a.id = b.id 然后就报错了,上网查了下知道oracle不能 ...

  7. 吴裕雄--天生自然java开发常用类库学习笔记:多线程基础编程

    class MyThread implements Runnable{ // 实现Runnable接口,作为线程的实现类 private String name ; // 表示线程的名称 public ...

  8. LeetCode160 相交链表(双指针)

    题目: click here!!题目传送门 思路: 1.笨方法 因为如果两个链表相交的话,从相交的地方往后是同一条链表,所以: 分别遍历两个链表,得出两个链表的长度,两个长度做差得到n,然后将长的链表 ...

  9. 原生searchView 自定义样式

    https://www.jianshu.com/p/f1fe616d630d 去除搜索框中的图标 <style name="SeachViewActivityTheme" p ...

  10. 关于如何实现一个Saga分布式事务框架的思考

    关于Saga模式的介绍,已经有一篇文章介绍的很清楚了,链接在这里:分布式事务:Saga模式. 关于TCC模式的介绍,也已经有一篇文章介绍的很清楚了,链接在这里:关于如何实现一个TCC分布式事务框架的一 ...