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

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. MD5加密解密类(asp.net)&使用MD5过时处理

    加密类 #region ========加密======== /// <summary> /// 加密 /// </summary> /// <param name=&q ...

  2. Java IO流篇

    什么是IO流 思考问题 如何读写文件? 解决--通过流读写文件 流是指一连串流动的字符,以先进先出传输信息的通道. Java操控硬盘上的文件,通过IO流来实现 Java流的分类 按流向区分 ---输出 ...

  3. PHP 生成水印图片

    这段时间因工作需要,学习了下用PHP来给背景图上添加公司logo,宣传语之类的图片合并功能.话不多说,直接上代码. <?php public function getImage() { $dat ...

  4. 2018最完整ITTO分节整理指导(PMP项目管理入门必备)

    2018年项目管理基础教材<PMBOK>指南进行了改版,之前的一些PMP资料没有太大帮助,反而会让大家记忆混淆,用最新的会好一些,今天小编就把搜集到的2018年项目管理最详细的ITTO的P ...

  5. Good Bye 2018

    Good Bye 2018 2018年最后一场CF,OVER! 弱弱的我只能做出3道A,B,D~~~~ 最后几分钟,感觉找到了C题的规律,结束的那一刻,提交了一发 "Wrong answer ...

  6. js中两种定时器,setTimeout和setInterval的区别

    setTimeout只在指定时间后执行一次,代码如下:   <script>   //定时器 异步运行   function hello(){   alert("hello&qu ...

  7. Vuex异步请求数据通过computed计算属性值

    问题描述: 使用Vuex管理数据时,在组件内使用$emit分发事件后,获取回来的数据要自动更新到该组件内,需要使用computed来计算更新. 一开始尝试使用赋值给data的方法,后来发现重新发起aj ...

  8. File的创建

    package cn.lijun.demo3; import java.io.File; import java.io.IOException; // 创建文件功能 如果文件已经存在 不再创建 pub ...

  9. Mysql+Keepalived双主热备高可用操作记录

    我们通常说的双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务.当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短.MySQL双主复制,即互为Mast ...

  10. 简洁架构的思想,基于go实现

    https://manuel.kiessling.net/2012/09/28/applying-the-clean-architecture-to-go-applications/ 从 Clean- ...