传送门

题意:给出长度为$N$的两个正整数序列$A_i,B_i$,求$\sum\limits_{i=1}^N \sum\limits_{j=i+1}^N C_{A_i+A_j+B_i+B_j}^{A_i+B_i}$。$N \leq 2 \times 10^5$


给出两种数据范围以及对应做法:

①$1 \leq A_i,B_i \leq 2000$(原题数据范围)

我们可以发现$C_{A_i+A_j+B_i+B_j}^{A_i+B_i}$就相当于在平面直角坐标系上限定每一次只能向上或者向右走一个单位的情况下,从$(-A_i,-B_i)$走到$(A_j,B_j)$的方案数量,所以原来的题目就可以抽象为一些第三象限的点限定每一次只能向上或者向右走一个单位的情况下走到第一象限中的任意一个点的方案数的和。我们可以将所有$(-A_i,-B_i)$的权值设为$1$,然后递推得到每一个$(A_j,B_j)$的方案数即可。注意:要将$(-A_i,B_i)$到$(A_i,B_i)$的路径方案数减掉(直接组合数即可),同时因为一个数对会被算两边,所以最后要乘上$2$的逆元。总时间复杂度为$O(N+\text{值域}^2)$

 #include<bits/stdc++.h>
 using namespace std;

 inline int read(){
     ;
     ;
     char c = getchar();
     while(c != EOF && !isdigit(c)){
         if(c == '-')
             f = ;
         c = getchar();
     }
     while(c != EOF && isdigit(c)){
         a = (a << ) + (a << ) + (c ^ ');
         c = getchar();
     }
     return f ? -a : a;
 }

  , MAXN =  , MAXM = ;
 ][MAXN + ] , jc[MAXN +  << ] = { , } , ny[MAXN +  << ] = {} , a[MAXM + ] , b[MAXM + ];

 inline long long poww(long long a , int b){
     ;
     while(b){
         )
             times = times * a % MOD;
         a = a * a % MOD;
         b >>= ;
     }
     return times;
 }

 int main(){
      ; i <= MAXN <<  ; i++)
         jc[i] = jc[i - ] * i % MOD;
     ny[MAXN << ] = poww(jc[MAXN << ] , MOD - );
     ) -  ; i ; i--)
         ny[i] = ny[i + ] * (i + ) % MOD;
     ;
      ; i <= N ; i++){
         a[i] = read();
         b[i] = read();
         f[-a[i] + ][-b[i] + ]++;
         ans = (ans + MOD - jc[a[i] + b[i] << ] * (] % MOD * ny[b[i] << ] % MOD) % MOD;
     }
      ; i <= MAXN ; i++){
         f[i][] += f[i - ][];
         f[][i] += f[][i - ];
     }
      ; i <= MAXN ; i++)
          ; j <= MAXN ; j++)
             f[i][j] = ((f[i][j] + f[i - ][j]) % MOD + f[i][j - ]) % MOD;
      ; i <= N ; i++)
         ans = (ans + f[a[i] + ][b[i] + ]) % MOD;
     cout << ans * poww( , MOD - ) % MOD;
     ;
 }

②$1 \leq A_i,B_i \leq 10^6 , \sum(A_i + B_i) \leq 2 \times 10^7$

注意到后面给的和的条件,思考如何去利用它。

将$C_{A_i+A_j+B_i+B_j}^{A_i+B_i}$稍微变形:

$C_{A_i+A_j+B_i+B_j}^{A_i+B_i}$

$= \sum\limits_{k=0}^{A_i+A_j} C_{A_i+B_i}^k \times C_{A_j+B_j}^{A_i+A_j-k}$

$= \sum\limits_{k=-A_i}^{A_j} C_{A_i+B_i}^{A_i+k} \times C_{A_j+B_j}^{A_j-k}$

$= \sum\limits_{k=-A_i}^{B_i} C_{A_i+B_i}^{A_i+k} \times C_{A_j+B_j}^{A_j-k}$

(至于最后一步,因为$k>B_i$时,$C_{A_i+B_i}^{A_i+k}=0$,而$k>A_j$时$C_{A_j+B_j}^{A_j-k}=0$,所以$A_j$与$B_i$是等价的)

所以我们维护$f_i$表示在计算$now$的答案时$\sum\limits_{j=1}^{now-1}C_{A_j+B_j}^{A_j-i}$的值,然后每一次通过$f$数组得到当前答案,并用当前的状态更新$f$数组即可。

复杂度$O(\sum(A_i + B_i) + N)$

 #include<bits/stdc++.h>
 using namespace std;

 inline int read(){
     ;
     ;
     char c = getchar();
     while(c != EOF && !isdigit(c)){
         if(c == '-')
             f = ;
         c = getchar();
     }
     while(c != EOF && isdigit(c)){
         a = (a << ) + (a << ) + (c ^ ');
         c = getchar();
     }
     return f ? -a : a;
 }

  , MAXN = ;
  << ] , jc[MAXN + ] = { , } , ny[MAXN + ] = {};

 inline long long poww(long long a , int b){
     ;
     while(b){
         )
             times = times * a % MOD;
         a = a * a % MOD;
         b >>= ;
     }
     return times;
 }

 int main(){
      ; i <= MAXN ; i++)
         jc[i] = jc[i - ] * i % MOD;
     ny[MAXN] = poww(jc[MAXN] , MOD - );
      ; i ; i--)
         ny[i] = ny[i + ] * (i + ) % MOD;
     ;
      ; i <= N ; i++){
         long long a = read() , b = read();
         for(int j = -a ; j <= b ; j++)
             ans = (ans + f[MAXN + j] * (long long)jc[a + b] % MOD * ny[a + j] % MOD * ny[b - j]) % MOD;
         for(int j = -b ; j <= a ; j++)
             f[MAXN + j] = (f[MAXN + j] + (long long)jc[a + b] * ny[a - j] % MOD * ny[b + j]) % MOD;
     }
     cout << ans % MOD;
     ;
 }

AGC001E BBQ Hard 组合、递推的更多相关文章

  1. 2825 codevs危险的组合(递推)

    2825 危险的组合 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有一些装有铀(用U表示)和铅(用L表示)的盒子,数量均足够 ...

  2. Crash的游戏 [组合+递推]

    题面 思路 问题转化 这个问题的核心在于,我们需要把"加入一个球.拿出一个球"这两个操作转化一下 因为显然两个操作同时进行的话,我们没有办法从单纯的组合意义去分析 我们首先把$m$ ...

  3. Codeforces Round #526 C - The Fair Nut and String /// 组合递推

    题目大意: 给定原字符序列 找出其中所有子序列满足 1.序列内字符都为a 2.若有两个以上的字符 则相邻两个字符在原序列中两者之间存在字符b 的数量 将整个字符序列用b分开 此时再得到每个b之间a的数 ...

  4. UVA 557 Burger 排列组合递推

    When Mr. and Mrs. Clinton's twin sons Ben and Bill had their tenth birthday, the party was held at t ...

  5. 逆元 组合A(n,m) C(n,m)递推 隔板法

    求逆元 https://blog.csdn.net/baidu_35643793/article/details/75268911 int inv[N]; void init(){ inv[] = ; ...

  6. P1759 通天之潜水(不详细,勿看)(动态规划递推,组合背包,洛谷)

    题目链接:点击进入 题目分析: 简单的组合背包模板题,但是递推的同时要刷新这种情况使用了哪些物品 ac代码: #include<bits/stdc++.h> using namespace ...

  7. 递推,求至少连续放置三个U的危险组合

    UVA580-Critical Mass 题意 有两种方块,L和U,有至少三个连续的U称为危险组合,问有多少个危险组合 solution: 至少这个概念比较难求 ,所以转化为(1ll<<n ...

  8. 【bzoj 2339】[HNOI2011]卡农(数论--排列组合+逆元+递推)

    题意:从编号为 1~N 的音阶中可选任意个数组成一个音乐片段,再集合组成音乐篇章.要求一个音乐篇章中的片段不可重复,都不为空,且出现的音符的次数都是偶数个.问组成 M 个片段的音乐篇章有多少种.答案取 ...

  9. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

随机推荐

  1. 虚拟 DOM

    虚拟DOM :virtual dom(以下简称vdom,是vue和react的核心),使用比较简单. 一,vdom是什么,为何会存在vdom 1,什么是vdom:用js模拟DOM结构,DOM操作非常‘ ...

  2. win7 x64 +vs2015 + cmake3.10.3编译opencv-3.4.1+opencv_contrib-3.4.1源码,并进行配置

    简介: 一直以来都是在ubuntu下使用opencv,最近因为有<图像处理与模式识别>这门课,需要使用vs2015+opencv提交课程作业,因为opencv官方编译好的exe没有cont ...

  3. loadrunner 脚本开发-定义全局变量

    脚本开发-定义全局变量 by:授客 QQ:1033553122 如果参数是全局的,在脚本中的任何一个Action中都可以使用,变量一般是局部的,如果跨Action调用会出现未声明的错误. 打开Scri ...

  4. Android ViewPager + Fragment实现滑动页面

    效果: PagerData类: package com.cloud.viewpagerdemo; import java.io.Serializable; class PagerData implem ...

  5. NoHttp封装--01

    NoHttpActivity public class NoHttpActivity extends Activity implements View.OnClickListener { privat ...

  6. django —— MVT模型

    转载----

  7. Mysqli面向对象操作数据库

    Mysqli面向对象操作数据库 首先配置一下数据库: 接着用PHP中的Mysqli扩展库面向对象查询这个数据表. 操作分为以下几个步骤: 连接数据库 操作数据库 处理结果 关闭资源 <?php ...

  8. 公式编辑器MathType基本使用方法总结----应付本科毕业论文完全没问题啦^_^

    本人计算数学专业毕业,写毕业论文和外文翻译的时候会遇到大量公式需要编辑,而且学校一般都要求用word.但是Word自带的公式编辑器只支持一种字体,当公式中涉及到特殊字体就不太方便了.如果用Latex来 ...

  9. CyclicBarrier源码解读

    1. 简介 JUC中的CyclicBarrier提供了一种多线程间的同步机制,可以让多个线程在barrier等待其它线程到达barrier.正如其名CyclicBarrier含义就是可以循环使用的屏障 ...

  10. JQuery中$.cookie()方法的使用[转]

    jquery.cookie.js插件: <script type="text/javascript" src="js/jquery-1.6.2.min.js&quo ...