很好的锻炼推柿子能力的题目

LOJ #2026


题意

有$n$个人$ m$门学科,第$ i$门的分数为不大于$U_i$的一个正整数

定义A「打爆」B当且仅当A的每门学科的分数都不低于B的该门学科的分数

已知第一个人第$ i$们学科的排名为$ R_i$,

即这门学科不低于$ n-R_i$人的分数,但一定低于$ R_i-1$人的分数

求有多少种方案使得第一个人恰好「打爆」了$ k$个人

两种方案不同当且仅当存在两个人的分数不同

$ n,m \leq 100 ,U_i \leq 10^9$


$ Solution$

首先容斥

设$ g_x$表示第一个人至少「打爆」了$ x$个人的方案数,

$ A_i$表示给所有人第$ i$门学科分配分数使得第一个人排名正确的方案数

$ g_x=\binom{n-1}{x} \prod\limits_{i=1}^m \binom{n-x-1}{n-x-R_i}A_i$

$A_i=\sum\limits_{j=1}^{U_i}j^{n-R_i}(U_i-j)^{R_i-1}$

$ g_x$的意义是

先选出被吊打的$ x$个人

再枚举每一门学科,这门学科比$ n-R_i$人高,

除去被吊打的$ x$人外还需要在未被吊打的$ n-x-1$人中选出$ n-R_i-x$人这门比第一个人低

然后再给这$ n$个人分配分数

$ A_i$的意义是:

枚举第一个人第$ i$门的分数$ j$,有$ n-R_i$人分数不能高于$j$,其余$ R_i-1$人分数必须高于$ j$

容易发现瓶颈在快速计算$ A_i$上

我们将$ A_i$二项式展开得

$A_i=\sum\limits_{j=1}^{U_i}j^{n-R_i}(U_i-j)^{R_i-1}$

$A_i=\sum\limits_{j=1}^{U_i}j^{n-R_i}\sum\limits_{k=0}^{R_i-1} \binom{R_i-1}{k}{(U_i)}^k(-j)^{R_i-k-1}$

$A_i=\sum\limits_{k=0}^{R_i-1} \binom{R_i-1}{k}{(U_i)}^k\sum\limits_{j=1}^{U_i}j^{n-R_i}(-j)^{R_i-k-1}$

$A_i=\sum\limits_{k=0}^{R_i-1} \binom{R_i-1}{k}{(U_i)}^k(-1)^{R_i-k-1}\sum\limits_{j=1}^{U_i}j^{n-k-1}$

前半部分非常好算

后半部分是一个自然数幂和,可以拉格朗日插值解决

拉格朗日插值过程中可以通过预处理前后缀的方式去掉不必要的求逆元复杂度使除预处理外单次$ O(n)$

这样就可以快速算出$ g_x$了

然后就是喜闻乐见的反演环节

设$ f_x$表示第一个人恰好「打爆」了$ x$个人

$ g_x=\sum\limits_{i=x}^n \binom{i}{x}f_i$

$ f_x=\sum\limits_{i=x}^n(-1)^{i-x} \binom{i}{x}g_i$

然后这道题就解决了

总复杂度:$ O(n^2m)$


$ my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define p 1000000007
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int i,j,k,m,n,x,y,z,cnt;
int C[][],f[],B[],U[],R[];
int ksm(int x,int y){
int ans=;
for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*ans*x%p;
return ans;
}
int mi[][];//前i个数的j次幂
int jc[],njc[],inv[];
int qz[],hz[];
int cz(int n,int k){
if(!k)return n;int ans=;
if(n<=)return mi[n][k];
int up=;qz[]=hz[k+]=;
for(rt i=;i<=k+;i++)qz[i]=1ll*qz[i-]*(n-i)%p;
for(rt i=k+;i>=;i--)hz[i]=1ll*hz[i+]*(n-i)%p;
for(rt i=;i<=k+;i++){
int down=1ll*njc[i-]*njc[k+-i]%p;
if(i+k&)down=-down;
(ans+=1ll*mi[i][k]*qz[i-]%p*hz[i+]%p*down%p%p)%=p;
}
return ans;
}
int main(){
jc[]=jc[]=njc[]=njc[]=inv[]=inv[]=;
for(rt i=;i<=;i++){
jc[i]=1ll*jc[i-]*i%p;
inv[i]=1ll*inv[p%i]*(p-p/i)%p;
njc[i]=1ll*njc[i-]*inv[i]%p;
}
for(rt i=;i<=;i++)
for(rt j=;j<=;j++)if(j==)mi[i][j]=i;else mi[i][j]=1ll*mi[i][j-]*i%p;
for(rt j=;j<=;j++)
for(rt i=;i<=;i++)mi[i][j]=(mi[i-][j]+mi[i][j])%p;
n=read();m=read();int K=read();
for(rt i=;i<=m;i++)U[i]=read();
for(rt i=;i<=m;i++)R[i]=read();
for(rt i=;i<=;i++){
C[i][]=;
for(rt j=;j<=i;j++)
C[i][j]=(C[i-][j]+C[i-][j-])%p;
}
for(rt i=;i<=m;i++){
for(rt k=;k<=R[i]-;k++){
int ret=;
(ret+=1ll*C[R[i]-][k]*ksm(U[i],k)%p*cz(U[i],n-k-)%p)%=p;
if(R[i]-k-&)(B[i]-=ret)%=p;else (B[i]+=ret)%=p;
}
}
for(rt i=;i<n;i++){
f[i]=;
for(rt j=;j<=m;j++){
if(n-i-R[j]<){
f[i]=;
break;
}
(f[i]=1ll*f[i]*C[n-i-][n-i-R[j]]%p*B[j]%p)%=p;
}
f[i]=1ll*f[i]*C[n-][i]%p;
}
int ans=;
for(rt j=K,tag=;j<n;j++,tag*=-)(ans+=1ll*f[j]*C[j][K]*tag%p)%=p;
cout<<(ans+p)%p;
return ;
}

LOJ #2026「JLOI / SHOI2016」成绩比较的更多相关文章

  1. loj #2026. 「JLOI / SHOI2016」成绩比较

    #2026. 「JLOI / SHOI2016」成绩比较   题目描述 THU 的 G 系中有许许多多的大牛,比如小 R 的室友 B 神.B 神已经厌倦了与其他的同学比较 GPA(Grade Poin ...

  2. 【LOJ】#2026. 「JLOI / SHOI2016」成绩比较

    题解 用\(f[i][j]\)表示考虑了前i个排名有j个人被碾压 \(f[i][j] = f[i - 1][k] \* C[k][j] \* C[N - k - 1][N - r[i] - j] \* ...

  3. loj #2024. 「JLOI / SHOI2016」侦查守卫

    #2024. 「JLOI / SHOI2016」侦查守卫   题目描述 小 R 和 B 神正在玩一款游戏.这款游戏的地图由 nnn 个点和 n−1n - 1n−1 条无向边组成,每条无向边连接两个点, ...

  4. loj #2025. 「JLOI / SHOI2016」方

    #2025. 「JLOI / SHOI2016」方   题目描述 上帝说,不要圆,要方,于是便有了这道题. 由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形.上帝把我们派到了一个有 NNN ...

  5. loj2026 「JLOI / SHOI2016」成绩比较

    orz #include <iostream> #include <cstdio> using namespace std; typedef long long ll; int ...

  6. 【LOJ】 #2025. 「JLOI / SHOI2016」方

    题解 有什么LNOI啊,最后都是JLOI罢了 一道非常--懵逼的统计题 当然是容斥,所有的方案 - 至少有一个点坏掉的正方形 + 至少有两个点坏掉的正方形 - 至少有三个点坏掉的正方形 + 至少有四个 ...

  7. 【LOJ】#2024. 「JLOI / SHOI2016」侦查守卫

    题解 童年的回忆! 想当初,这是我考的第一次省选,我当时初二,我什么都不会,然后看着这个东西,是不是能用我一个月前才会的求lca,光这个lca我就调了一个多小时= =,然后整场五个小时,我觉得其他题不 ...

  8. loj2024「JLOI / SHOI2016」侦查守卫

    too hard #include <iostream> #include <cstdio> using namespace std; int n, d, m, uu, vv, ...

  9. Loj #2495. 「AHOI / HNOI2018」转盘

    Loj #2495. 「AHOI / HNOI2018」转盘 题目描述 一次小 G 和小 H 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1 ...

随机推荐

  1. Web Deploy 服务器安装设置与使用

    一.服务器的安装设置 1.在windows server上确保IIS安装了[管理服务]这个功能.方法是在[服务器管理器]=>[管理]=>[添加角色和功能]=>[下一步]=>[基 ...

  2. Luogu P1251 餐巾计划问题

    题目链接 \(Click\) \(Here\) 看到其他人都是用费用流写的,我只能表示:动什么脑子?暴力就完事了! 嗯,这个题应该是一个相当显然的上下界最小费用可行流模型,所以跑就完事了. \(s - ...

  3. 流明(lux)和坎德拉;

    流明是光照度:  坎德拉是光强: 流明是光通量的单位, cd是光强单位 光强是单位立体角的光通量: 照度是单位面积的光通量: 尼特是亮度单位   1尼特 = 1CD/m^2: 1 lx = 1 流明每 ...

  4. 缓存淘汰策略之LRU

    LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1. 新数据插入到链表头部: ...

  5. rancher使用fluentd-pilot收集日志分享

    fluentd-pilot简介 fluentd-pilot是阿里开源的docker日志收集工具,Github项目地址:https://github.com/AliyunContainerService ...

  6. C# enum、int、string三种类型互相转换

    enum.int.string三种类型之间的互转 #代码: public enum Sex { Man=, Woman= } public static void enumConvert() { in ...

  7. Java的内省机制

    我现在的理解就是,Java的内省机制就是针对JavaBean的,可以获取到类的属性名称,以及属性的Getter和Setter方法,应该是在写框架的时候才会用到内省机制,还有一个地方可以用到内省机制,就 ...

  8. C#设计模式(2)——工厂模式

    1.工厂模式介绍 上一篇我们知道了简单工厂的缺点是:当我们添加一个新的产品时需要修改工厂类,这样就违背了开闭原则.工厂模式就是为了解决这一缺陷而出现的,解决的方法是把创建具体实例的任务放在了工厂的子类 ...

  9. Spark源码剖析 - SparkContext的初始化(三)_创建并初始化Spark UI

    3. 创建并初始化Spark UI 任何系统都需要提供监控功能,用浏览器能访问具有样式及布局并提供丰富监控数据的页面无疑是一种简单.高效的方式.SparkUI就是这样的服务. 在大型分布式系统中,采用 ...

  10. 如何转换cdr文件

    You will need to copy the type library from corelDRAW: C:\Program Files (x86)\Corel\CorelDRAW Graphi ...