题面

传送门

题解

首先区间个数很少,我们考虑把所有区间离散化(这里要把所有的右端点变为\(B_i+1\)代表的开区间)

设\(f_{i,j}\)表示考虑到第\(i\)个学校且第\(i\)个学校必选,这个学校选择的数在离散后的第\(j\)个区间内,方案数是多少

怎么转移呢,我们考虑枚举上一个不在第\(j\)个区间的学校\(k\),设\([k+1,i]\)中有\(a\)个学校是可以选在第\(j\)个区间的,且第\(j\)个区间的长度为\(b\),然后暴力枚举这\(m\)个数中有\(q\)个选了,那么转移就是

\[f_{i,j}=\sum_{k=0}^{i-1}\left(\sum_{p=0}^{j-1}f_{k,p}\right)\sum_{q=1}^{\min(a,b)}{a-1\choose q-1}{b\choose q}
\]

\(\sum_{p=0}^{j-1}f_{k,p}\)显然是可以做一个前缀和的

然后对于\(\sum_{q=1}^{\min(a,b)}{a-1\choose q-1}{b\choose q}\),它等于\(\sum_{q=1}^{\min(a,b)}{a-1\choose a-q}{b\choose q}\),可以理解为有\(a+b-1\)个数,要选出\(a\)个,然后枚举前\(a-1\)个数里选了多少个和后\(b\)个里选了多少个,那么上面的柿子就等价于\({a+b-1\choose a}\)

于是递推式就可以化为

\[f_{i,j}=\sum_{k=0}^{i-1}{a+b-1\choose a}\left(\sum_{p=0}^{j-1}f_{k,p}\right)
\]

然后没有然后了

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=1005,P=1e9+7;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int A[N],B[N],D[N],inv[N],len[N],C[N],f[N][N],g[N][N];
int n,m,res;
int main(){
// freopen("testdata.in","r",stdin);
n=read();
fp(i,1,n)A[i]=read(),B[i]=read(),D[++m]=A[i],D[++m]=B[i]+1;
D[++m]=0,sort(D+1,D+1+m),D[m+1]=D[m]+1,m=unique(D+1,D+m+2)-D-1;
fp(i,1,m-1)len[i]=D[i+1]-D[i];
fp(i,1,n){
A[i]=lower_bound(D+1,D+1+m,A[i])-D,
B[i]=upper_bound(D+1,D+1+m,B[i])-D-1;
}
--m;
inv[0]=inv[1]=1;fp(i,2,n)inv[i]=mul(P-P/i,inv[P%i]);
f[0][0]=1;
fp(i,0,m)g[0][i]=1;
fp(i,1,n){
for(R int j=A[i],a,b;j<=B[i];++j){
a=len[j]-1,b=0,C[i]=1;
fd(k,i-1,0)
A[k+1]<=j&&B[k+1]>=j?(C[k]=1ll*(++a)*inv[++b]%P*C[k+1]%P):C[k]=C[k+1];
fd(k,i-1,0)f[i][j]=add(f[i][j],mul(C[k],g[k][j-1]));
}
g[i][0]=f[i][0];
fp(j,1,m)g[i][j]=add(f[i][j],g[i][j-1]);
res=add(res,g[i][m]);
}
printf("%d\n",res);
return 0;
}

洛谷P3643 [APIO2016]划艇(组合数学)的更多相关文章

  1. [洛谷P3643] [APIO2016]划艇

    洛谷题目链接:[APIO2016]划艇 题目描述 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 \(N\) 个划艇学校,编号依次为 \(1\) 到 \(N\).每个学校都拥有若干艘 ...

  2. 洛谷 P3643 - [APIO2016]划艇(dp)

    题面传送门 一道难度中等的 \(dp\)(虽然我没有想出来/kk). 首先一眼 \(dp_{i,j}\) 表示考虑到第 \(i\) 个学校,第 \(i\) 个学校派出了 \(j\) 个划艇的方案数,转 ...

  3. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

  4. P3643 [APIO2016]划艇

    P3643 [APIO2016]划艇 题意 一个合法序列可表示为一个长度为 \(n\) 的序列,其中第 \(i\) 个数可以为 0 或 \([l_i,r_i]\) 中一个整数,且满足所有不为零的数组成 ...

  5. LOJ 2567: 洛谷 P3643: bzoj 4584: 「APIO2016」划艇

    题目传送门:LOJ #2249. 题意简述: 有 \(n\) 个位置,第 \(i\) 个位置可以填在 \([a_i,b_i]\) (\(1\le a_i\le b_i\le 10^9\))之间的整数, ...

  6. [组合][DP]luogu P3643 [APIO2016]划艇

    题面 https://www.luogu.com.cn/problem/P3643 对于一个序列,第i项可取的值在{0}∪[ai,bi]之间,求使序列非零部分单调递增的方案数 分析 设 $f[i][j ...

  7. 题解 P3643 [APIO2016]划艇

    题解 一种思路很好想:\(f_{i,j}\) 表示前 \(i\) 所学校中,第 \(i\) 所学校参赛且派出 \(j\) 艘划艇的方案数.(转移就不列了.) 这种方式有一个致命点,就是 \(j\) 的 ...

  8. 洛谷P4562 [JXOI2018]游戏(组合数学)

    题意 题目链接 Sol 这个题就比较休闲了. \(t(p)\)显然等于最后一个没有约数的数的位置,那么我们可以去枚举一下. 设没有约数的数的个数有\(cnt\)个 因此总的方案为\(\sum_{i=c ...

  9. 洛谷P3642 [APIO2016]烟火表演

    传送门 题解 fy大佬好强……我根本看不懂…… //minamoto #include<bits/stdc++.h> #define ll long long using namespac ...

随机推荐

  1. python pipenv 包管理

    原文链接:https://robots.thoughtbot.com/how-to-manage-your-python-projects-with-pipenv 翻译者:Jiong 在thought ...

  2. drbd switch off

    DRBD secondary to primary: drbdadm disconnect all drbdadm primary r0 --force mount /dev/drbd0 /mnt [ ...

  3. 66. Plus One 数组加1

    [抄题]: Given a non-negative integer represented as a non-empty array of digits, plus one to the integ ...

  4. Hive入门学习随笔(二)

    ====使用Load语句执行数据的导入 --将操作系统上的文件student01.txt数据导入到t2表中 load data local inpath '/root/data/student01.t ...

  5. ACM暑假培训宣讲稿

    (鞠躬)感谢大家的掌声! 我上台来作这次的宣讲,首先要感谢大家的捧场(当然,这是一句玩笑话),其实吧,我要感谢一下我们ACM班老大(班长),hjh队友,是他指派我来的,给了我这个宝贵的机会.最要感谢的 ...

  6. springboot启动正常,访问restController报404

    原因:spring boot只会扫描启动类当前包和以下的包 比如以下: 主类:Application放在包com.springboot.main controller类放在包com.springboo ...

  7. javascript总结22: javascript的对象--面向对象编程

    1 对象:JavaScript 中的所有事物都是对象:字符串.数值.数组.函数. 对象与程序的关系: 程序 = 基于对象操作的算法 + 以对象为最小单位的数据结构 此外: 面向对象的本质就是让对象有多 ...

  8. Hadoop压缩之CompressionCodecFactory

    1.CompressionCodecFactory简介 当在读取一个压缩文件的时候,可能并不知道压缩文件用的是哪种压缩算法,那么无法完成解压任务.在Hadoop中,CompressionCodecFa ...

  9. 使用#include消除重复代码

    消除重复代码代码很多种,比如: 1)提炼成函数复用 2)使用宏 3)继承 4)使用闭包(boost::bind.boost::function) 上述是最为常用的,对于C++程序,闭包可能用得相对少一 ...

  10. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...