题目分析:

我们可以对每一条边单独计算贡献,这样会发现贡献很好算:

\[ans = \sum_{i=0}^{n-1} w_i \sum_{j=0}^S |j - s_i| \binom{i+j-1}{i-1}\binom{S - j + n - i - 1}{n - i - 1}
\]

这样就可以直接40跑路了

上面假设 \(s_i\) 为 \(a\) 的前缀和。

发现难算的就是第二个求和里面的那些,所以就考虑单独考虑,第一步肯定是化绝对值,化出来就是这个样子的:

\[\sum_{j=0}^S (j - s_i) \binom{i+j-1}{i-1}\binom{S - j + n - i - 1}{n - i - 1} + 2 \times \sum_{j=0}^{s_i} (s_i - j) \binom{i+j-1}{i-1}\binom{S - j + n - i - 1}{n - i - 1}
\]

前后其实本质上是一个东西啦,就选后面的去分析吧。

拆开后就是下面这些:

\[s_i \sum_{j=0}^{s_i}\binom{i+j-1}{i-1}\binom{S - j + n - i - 1}{n - i - 1} - \sum_{j=0}^{s_i} j \times \binom{i+j-1}{i-1}\binom{S - j + n - i - 1}{n - i - 1}
\]

其实这个式子我们是有一种冲动的,就是想把它们化的整齐一点,方便合并同类项,那么关键也就是化一下后面的式子啦。

其实就可以化为:

\[i \times \sum_{j=0}^{s_i} \binom{i+j-1}{i}\binom{S - j + n - i - 1}{n - i - 1}
\]

为了舒服一些,我们设出一个 \(f(n,s,i,k)\),其代表:

\[f(n,s,i,k) = \sum_{j=0}^{k}\binom{i+j-1}{i-1}\binom{s - j + n - i - 1}{n - i - 1}
\]

这样我们就可以很轻松地表示出上面这个式子了,即:

\[\sum_{j=0}^{s_i} \binom{i+j-1}{i}\binom{S - j + n - i - 1}{n - i - 1} = f(n+1,S-1,i-1,s_i+1)
\]

其实就是看看怎么把 \(f\) 那个式子变换成这个式子,剩下就不详细说了,这样我们最后的答案就可以表示为:

\[i \times f(n + 1,S - 1,i+1,S-1) - s_i \times f(n,S,i,S) + 2 \times s_i \times f(n,S,i,s_i) - 2 \times i \times f(n+1,S-1,i+1,s_i-1)
\]

我们可以发现因为 \(i,s_i\) 单调递增,所以如果我们可以快速做到由 \(f(n,s,i,k)\) 得到 \(f(n,s,i+1,k)\) 和 \(f(n,s,i,k+1)\) 就可以用线性的复杂度解决问题

可以根据定义直接得到 \(f(n,s,i,k+1)\),但是剩下的那个就很难弄了。

这个时候就要用的 \(f\) 一个很神仙的组合意义:\(s\) 个相同的小球放到 \(n\) 个不同的盒子里,要求前 \(i\) 个盒子放的小球总数小于等于 \(k\) 的方案数。

这个根据定义是很好理解的,每次就是枚举前 \(i\) 个盒子放多少个然后一个插板法。

这个意义其实换句话来说就是:从左到右第 \(k+1\) 个小球一定放在大于编号 \(i\) 的盒子里。那么此时如果我们枚举第 \(k+1\) 个小球放在哪个盒子里,最后得到的式子就是:

\[f(n,s,i,k) = \sum_{j = i+1}^{n} \binom{j + k - 1}{j-1} \binom{n - j + s - k - 1}{n - j}
\]

这个式子就可以解决 \(i\) 的移动了。

这个式子的具体意义就是:\(k\) 个小球放到前 \(j\) 个盒子里,\(s - k - 1\) 个小球放到剩下的 \(n - j + 1\) 个盒子里,这里主要是要注意第 \(j\) 个盒子我们钦定放了第 \(k+1\) 个球,但不一定仅仅是放了这一个。

代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e6+5;
const int MOD = 998244353;
int fac[N],inv[N],sum[N],w[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int mod(int x){
if(x < 0) return (x%MOD + MOD)%MOD;
else return x % MOD;
}
int binom(int n,int m){
if(n < m || n < 0 || m < 0) return 0;
return mod(fac[n] * mod(inv[m] * inv[n - m]));
}
struct fun{
int n,s,i,k,res;
void init(int _n,int _s,int _i,int _k){
n = _n,s = _s,i = _i,k = _k;res = 0;
for(int j=0; j<=k; j++){
res = mod(res + binom(i + j - 1,i - 1) * binom(s - j + n - i - 1,n - i - 1));
}
}
void movei(int x){
if(x <= i) return;
for(int j=i+1; j<=x; j++){
res = mod(res - binom(j + k - 1,j - 1) * binom(s - k - 1 + n - j,n - j));
}
i = x;
}
void movek(int x){
if(x <= k) return;
for(int j=k+1; j<=x; j++){
res = mod(res + binom(i + j - 1,i - 1) * binom(s - j + n - i - 1,n - i - 1));
}
k = x;
}
}f1,f2,f3,f4;
int power(int a,int b){
int res = 1;
while(b){
if(b & 1) res = mod(res * a);
a = mod(a * a);
b >>= 1;
}
return res;
}
void pre_work(int n){
fac[0] = 1;
for(int i=1; i<=n; i++) fac[i] = mod(fac[i-1] * i);
inv[n] = power(fac[n],MOD-2);
for(int i=n-1; i>=0; i--) inv[i] = mod(inv[i+1] * (i+1));
}
signed main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
pre_work(3000000);
int T = read();
while(T--){
int n = read();
for(int i=1; i<=n; i++){
int a = read();
sum[i] = sum[i-1] + a;
}
for(int i=1; i<n; i++) w[i] = read();
int ans = 0,S = sum[n];
f1.init(n+1,S-1,1,S-1);f2.init(n,S,1,S); //只要保证单调增,初值都没啥问题的
f3.init(n,S,1,0);f4.init(n+1,S-1,1,-1);
for(int i=1; i<n; i++){
// printf("%lld %lld %lld %lld\n",f1.res,f2.res,f3.res,f4.res);
int tmp = 0;
f1.movei(i+1);f2.movei(i);f3.movei(i);f3.movek(sum[i]);
f4.movei(i+1);f4.movek(sum[i] - 1);
tmp = mod(tmp + i * f1.res);
tmp = mod(tmp - sum[i] * f2.res);
tmp = mod(tmp + 2 * sum[i] * f3.res);
tmp = mod(tmp - 2 * i * f4.res);
ans = mod(ans + w[i] * tmp);
}
printf("%lld\n",ans);
}
return 0;
}

也可能是我的取模过于离谱,这个题竟然有点卡常。

【题解】[LNOI2022] 盒的更多相关文章

  1. [LNOI2022]盒

    \(LNOI2022\)盒 由于是加的形式,那么可以套路的拆贡献,枚举每条边的贡献就好了 \(40pts\) //比较显然的事情 //首先确定了一个B数组之后 //最小的移动应该是 //设左右两侧比原 ...

  2. 题解 [BZOJ4368][IOI2015]boxes纪念品盒

    题面 解析 可以发现,发纪念品有三种方式: 从左边走再原路返回. 从右边走再原路返回. 走一圈. 注意到,第三种走法最多只会走一次, 因为如果走了多次,那发放的物品数量就会>=\(2k\), 那 ...

  3. 二模Day2题解

    小明搬家 题目描述 小明要搬家了,大家都来帮忙. 小明现在住在第N楼,总共K个人要把X个大箱子搬上N楼. 最开始X个箱子都在1楼,但是经过一段混乱的搬运已经乱掉了.最后大家发现这样混乱地搬运过程效率太 ...

  4. 2018.11.26 QLU新生赛部分题解

    问题 L: 寄蒜几盒? 题目描述 现在有一个圆圈,圆圈上有若干个点,请判断能否在若干个点中选择三个点两两相连组成一个等边三角形? 这若干个点在圆圈上按顺时针顺序分布. 如果可以的话输出"Ye ...

  5. openjudge666:放苹果—题解

    (测试这里的markdown,同时也有纪念意义吧--第一次写的题解) 当时刚学递推的时候做的一道题 oj上的666题 666:放苹果 总时间限制: 1000ms 内存限制: 65536kB 描述 把M ...

  6. 【KMP】洛谷P2375 [NOI2014]动物园 题解

        一开始的方向应该对了,但是没有想到合理的优化还是没写出来…… 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己 ...

  7. 洛谷 题解 P1287 【盒子与球】

    题解:P1287 盒子与球 不了解的:stirling数(斯特林数) - 百度百科 分析如下: 设有n个不同的球,分别用b1,b2,--bn表示.从中取出一个球bn,bn的放法有以下两种: 1) bn ...

  8. IOI2015 boxes纪念品盒

    BZOJ 4368: [IOI2015]boxes纪念品盒 BZOJ传送门 Description IOI2015开幕式正在进行最后一个环节.按计划在开幕式期间,每个代表队都将收到由主办方发放的一个装 ...

  9. [bzoj4368][IOI2015]boxes纪念品盒_动态规划_单调队列_贪心

    bzoj4368 IOI2015 boxes纪念品盒 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=4368 数据范围:略. 题解: 如果在一个最 ...

  10. css_02之盒模型、渐变

    1.框模型:盒模型,①对象实际宽度=左右外边距+左右边框+左右内边距 + width:②对象实际高度=上下外边距+上下边框+上下内边距 + height: 2.外边距:margin:取值:①top(上 ...

随机推荐

  1. 五、Python操作redis

    五.Python操作redis 一.python对redis基本操作 (1)连接redis # 方式1 import redis r = redis.Redis(host='127.0.0.1', p ...

  2. 小菜鸡的学习笔记---<正则表达式(1)>

    正则表达式学习笔记(1) (纯新手学习笔记,大佬绕路 QAQ) 一.简介 正则表达式就是一种文本模式用来匹配一系列满足特定条件的字符串,可以对比一下数学里面的表达式,比如我们要用一个表达式表示一串数字 ...

  3. 论文笔记 - An Explanation of In-context Learning as Implicit Bayesian Inference

    这位更是重量级.这篇论文对于概率论学的一塌糊涂的我简直是灾难. 由于 prompt 的分布与预训练的分布不匹配(预训练的语料是自然语言,而 prompt 是由人为挑选的几个样本拼接而成,是不自然的自然 ...

  4. 将Oracle数据库迁移到达梦数据库

    公司某产品在项目现场上常用到的数据库有Oracle和达梦. 做性能测试需要根据项目现场预埋大量的基础数据和业务数据,耗费时间.精力.故完成Oracle数据库的性能测试之后,采用直接将Oracle数据库 ...

  5. 2022春每日一题:Day 25

    题目:青蛙的约会 读完题,显然可以的到下同余方程:x+mk≡y+nk (mod L) 移项变成 (m-n)k+aL=y-x 只有k,L是未知的,而这题要求非负整数k的最小值,显然拓展欧几里得算法. 然 ...

  6. 秦皇岛2020CCPC补题

    秦皇岛2020CCPC A,E,F,G,I,K A. A Greeting from Qinhuangdao 知识点:简单题 复杂度:\(O(logn)\) #include<bits/stdc ...

  7. VS 生成后事件中自动修改文件名插入当前时间

    目录 rename 指令 获取当前时间 将当前时间插入名字 rename 指令 VS 生成后事件中使用的是CMD 的语法 我们重命名使用的是Rename 简单用法如下: RENAME (REN) [d ...

  8. mingw+CLion环境下在Windows下编译配置并使用opencv

    目录 安装(mingw环境) 在项目中使用opencv QtCreator使用opencv 安装(mingw环境) vs环境没配过不知道 下载地址 解压到目标目录     解压后的目录结构(build ...

  9. 【JVM调优】Day04:总结前三日内容(GC+算法*4+简单回收器*3三色标记,CMS+G1+ZGC,参数个数+OOM+调优参数)

  10. 【每日一题】【排序】2021年11月13日-215. 数组中的第K个最大元素※

    给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素. 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 方法1:调库 class Solution ...