题意大致是有n个苹果,问你最多拿走m个苹果有多少种拿法。题目非常简单,就是求C(n,0)+...+C(n,m)的组合数的和,但是询问足足有1e5个,然后n,m都是1e5的范围,直接暴力的话肯定时间炸到奶奶都不认识了。当时想了好多好多,各种骚操作都想了一遍就是没想到居然是莫队....我用S(n,m)来记录C(n,0)+...+C(n,m)的和作为一个询问的答案

由组合数公式C(n,m) = C(n-1,m-1)+C(n-1,m)可以推的下面的式子

S(n,m) = S(n,m-1) + C(n,m);

S(n,m) = S(n,m+1) - C(n,m+1);

S(n,m) = 2*S(n-1)-C(n,m);

S(n,m) = ( S(n+1, m) + C(n,m) ) / 2;

这样发现居然是一个莫队的基本操作....然而只知道这几点也是不够的,因为组合数计算涉及到除法,所以得求逆元,还是阶乘的逆元,所以得先预处理出1~n的阶乘和它们的逆元,求逆元也是很耗时间的,但是我们可以通过递推一遍把阶乘的逆元求出来

  1. f(x)为x的逆元
  2. 那么 f(n!) = f( (n-)!*n ) = f((n-)!)*f(n);
  3. f(n)除过来 f(n!)*f(f(n)) = f((n-)!)
  4. 因为x的逆元的逆元就是x本身, 因此得到公式f(n!)*n = f((n-1)!),这样我们只要求出最大的阶乘的逆元就可以从大到小推出所有逆元的值

就酱(顺便说一句不知道为啥hdu选c++会TLE或者WA,得用G++编译)

  1. #include <iostream>
  2. #include <string.h>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <queue>
  6. #include <stack>
  7. #include <math.h>
  8. #include <string>
  9. #include <algorithm>
  10. #include <functional>
  11.  
  12. #define SIGMA_SIZE 26
  13. #define lson rt<<1
  14. #define rson rt<<1|1
  15. #define lowbit(x) (x&-x)
  16. #define foe(i, a, b) for(int i=a; i<=b; i++)
  17. #define fo(i, a, b) for(int i=a; i<b; i++)
  18. #define pii pair<int,int>
  19. #pragma warning ( disable : 4996 )
  20.  
  21. using namespace std;
  22. typedef long long LL;
  23. inline double dMax(double a, double b) { return a>b ? a : b; }
  24. inline double dMin(double a, double b) { return a>b ? b : a; }
  25. inline LL LMax(LL a, LL b) { return a>b ? a : b; }
  26. inline LL LMin(LL a, LL b) { return a>b ? b : a; }
  27. inline LL lgcd(LL a, LL b) { return b == ? a : lgcd(b, a%b); }
  28. inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm
  29. inline int Max(int a, int b) { return a>b ? a : b; }
  30. inline int Min(int a, int b) { return a>b ? b : a; }
  31. inline int gcd(int a, int b) { return b == ? a : gcd(b, a%b); }
  32. inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm
  33. const LL INF = 0x3f3f3f3f3f3f3f3f;
  34. const LL mod = 1e9+;
  35. const double eps = 1e-;
  36. const int inf = 0x3f3f3f3f;
  37. const int maxk = 3e6 + ;
  38. const int maxn = 1e5+;
  39.  
  40. int n, m, unit;
  41. int belong[maxn];
  42. LL fac[maxn], inv[maxn],invof2;
  43. LL ans[maxn];
  44. struct node {
  45. int lhs, rhs, id;
  46. }pp[maxn];
  47.  
  48. bool cmp(const node& a, const node& b)
  49. {
  50. if (belong[a.lhs] == belong[b.lhs])
  51. return (belong[a.lhs]&) ? a.rhs<b.rhs : a.rhs>b.rhs;
  52. return a.lhs < b.lhs;
  53. }
  54.  
  55. //设f(x)为x的逆元
  56. //f(n!) = f( (n-1)!*n ) = f((n-1)!)*f(n);
  57. //将f(n)除过来 f(n!)*f(f(n)) = f((n-1)!)
  58. //因此可以从最大的n反向推回小的
  59. LL getM( LL a, LL b, LL m)
  60. {
  61. LL ans = , base = a;
  62. while (b)
  63. {
  64. if ( b & )
  65. ans = (ans*base) % m;
  66. base = (base*base) % m;
  67. b >>= ;
  68. }
  69. return ans;
  70. }
  71.  
  72. void init()
  73. {
  74. fac[] = fac[] = ;
  75. inv[] = inv[] = ;
  76. foe(i, , maxn)
  77. fac[i] = fac[i-]*i%mod;
  78.  
  79. inv[maxn-] = getM(fac[maxn-], mod-, mod);
  80. invof2 = getM(, mod-, mod);
  81. for ( int i = maxn-; i >= ; i-- )
  82. inv[i] = (inv[i+]*(i+))%mod;
  83. }
  84.  
  85. LL C(int down, int up)
  86. {
  87. if ( up > down ) return ;
  88. return fac[down]*inv[up]%mod*inv[down-up]%mod;
  89. }
  90.  
  91. int main()
  92. {
  93. init();
  94. int T;
  95. cin >> T;
  96. unit = sqrt(T);
  97.  
  98. foe(i, , T)
  99. {
  100. scanf("%d %d", &n, &m);
  101. pp[i].lhs = n; pp[i].rhs = m;
  102. pp[i].id = i;
  103. belong[i] = i/unit+;
  104. }
  105. sort(pp+, pp++T, cmp);
  106.  
  107. //(l代表n, r代表m)
  108. int l = , r = ;
  109. LL sum = ;
  110.  
  111. for ( int i = ; i <= T; i++ )
  112. {
  113. while (r < pp[i].rhs) {
  114. r++;
  115. sum = (sum + C(l, r))%mod;
  116. }
  117.  
  118. while (r > pp[i].rhs) {
  119. sum = (sum - C(l, r)+mod)%mod;
  120. r--;
  121. }
  122.  
  123. while (l < pp[i].lhs) {
  124. sum = ((LL)*sum - C(l, r)+mod)%mod;
  125. l++;
  126. }
  127.  
  128. while (l > pp[i].lhs) {
  129. l--;
  130. sum = (sum+C(l,r))%mod*invof2%mod;
  131. }
  132.  
  133. ans[pp[i].id] = sum;
  134. }
  135.  
  136. foe(i, , T)
  137. printf("%lld\n", ans[i]);
  138. return ;
  139. }

Harvest of Apples (HDU多校第四场 B) (HDU 6333 ) 莫队 + 组合数 + 逆元的更多相关文章

  1. 2018 HDU多校第四场赛后补题

    2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...

  2. HDU 多校第四场题解

    对于 D 题的原题意,出题人和验题人赛前都没有发现标算存在的问题,导致了许多选手的疑惑和时间的浪费,在此表示真诚的歉意! 预计难度分布: Easy - DJKL, Medium - ABCEG, Ha ...

  3. HDU 6333 莫队+组合数

    Problem B. Harvest of Apples Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K ...

  4. 2014多校第四场1006 || HDU 4902 Nice boat (线段树 区间更新)

    题目链接 题意 : 给你n个初值,然后进行两种操作,第一种操作是将(L,R)这一区间上所有的数变成x,第二种操作是将(L,R)这一区间上所有大于x的数a[i]变成gcd(x,a[i]).输出最后n个数 ...

  5. 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

    题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位 ...

  6. hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题

    题意: 给你重量分别为1到n的n个石头,让你分成重量相等,数量也相等的k组,保证k是n的约数.问你能不能分配,如果能,输出具体的分配方案. 题解: 首先,如果1到n之和不能整除k,那么一定不能如题意分 ...

  7. hdu多校第四场 1007 (hdu6620) Just an Old Puzzle 逆序对

    题意: 给你一个数字拼图,问你数字拼图能否能复原成原来的样子. 题解: 数字拼图的性质是,逆序数奇偶相同时,可以互相转化,逆序数奇偶不同,不能互相转化. 因此统计逆序对即可. #include< ...

  8. hdu多校第四场1001 (hdu6614) AND Minimum Spanning Tree 签到

    题意: 一个完全图,某两点边权为这两点编号之按位与,求最小生成树,输出字典序最小的. 题解: 如果点数不为$2^n-1$,则每一点均可找到一点,两点之间边权为0,只需找到该点二进制下其最左边的0是第几 ...

  9. 2018 HDU多校第三场赛后补题

    2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...

随机推荐

  1. Android Studio Gradle无法获取pom文件

    错误提示: Error:Execution failed for task ':app:lintVitalRelease'. > Could not resolve all artifacts ...

  2. php 三种文件下载的实现

    第一种:直接添加文件下载的绝对路径连接 //如:我有一个文件在demo.xx.cn/demo.zip <button> <a href = "http://demo.xx. ...

  3. Helvetic Coding Contest 2018 online mirror (teams allowed, unrated)F3 - Lightsabers (hard)

    题意:n个数字1-m,问取k个组成的set方案数 题解:假设某个数出现k次,那么生成函数为\(1+x+...+x^k\),那么假设第i个数出现ai次,结果就是\(\sum_{i=1}^m(1+x+.. ...

  4. duilib教程之duilib入门简明教程6.XML配置界面

    前面那些教程都是为了让小伙伴们从win32.MFC过渡到duilib,让大家觉得duilib不是那么陌生,如果大家现在还对duilib非常陌生的话,那就说明前面的教程做得不好,请大家在下面留言,我会一 ...

  5. Wed Nov 01 13:03:16 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended.

    报错:Wed Nov 01 13:03:16 CST 2017 WARN: Establishing SSL connection without server's identity verifica ...

  6. VS中检测数据库链接

    在程序中链接数据库,总要为链接语句发愁.可以尝试在链接前,从VS中测试下链接,测试成功的话,可以直接将链接语句复制到程序中. 在VS中,选择“工具”——“连接到数据库”,如下:

  7. 第二周课堂笔记2th

    ---恢复内容开始--- 1. 2.索引取单个值 取多个值叫切片, 切片:取多个值 从左到右取值: 原则:顾头不顾尾 1, a[0:3] abc 2, a[-5:-2] abc 3, a[0:-2] ...

  8. Nodejs之路(三)—— Nodejs之Express框架

    Express 原生的 http 在某些方面表现不足以应对我们的开发需求,所以我们需要使用框架来加快我们的开发效率.框架的目的就是提高效率,让我们的代码更高度统一 在Node 中,有很多 Web 开发 ...

  9. 拦截器和自定义注解@interface

    1 .拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在Handler执行之前或之后加入某些操作,其实就是AOP的一种实现策略. 拦截用户的请求并进行相应的处理,比如:判断用 ...

  10. 廖雪峰Java13网络编程-1Socket编程-1网络编程概念

    1.计算机网络 1.1 什么是计算机网络? 两台或更多计算机组成的网络 同一网络内的任意2台计算机都可以直接通信 所有计算机必须遵循同一种网络协议 1.2 什么是互联网 互联网是网络的网络 互联网采用 ...