• HDU


    原题链接

    题意:

    一颗苹果树上有 $n$ 个苹果, 编号从 $1...n$ ,问最多取 $m$ 个苹果有多少种取法。

    思路:

    就是求       但是 $T, n ,m$ 均是 $1e5$ 的范围,直接求肯定爆炸,但此题只有查询,我们就可以用莫队来做,离线查询从而减少复杂度;

    以上性质可推导求得,然后我们就可以用莫队进行状态的转移;

      1 /*
      2 * @Author: windystreet
      3 * @Date:   2018-08-03 14:45:03
      4 * @Last Modified by:   windystreet
      5 * @Last Modified time: 2018-08-03 16:42:19
      6 */
      7 #include<bits/stdc++.h>
      8 
      9 using namespace std;
     10 
     11 #define X first
     12 #define Y second
     13 #define eps  1e-2
     14 #define gcd __gcd
     15 #define pb push_back
     16 #define PI acos(-1.0)
     17 #define lowbit(x) (x)&(-x)
     18 #define bug printf("!!!!!
    ");
     19 #define mem(x,y) memset(x,y,sizeof(x))
     20 
     21 typedef long long LL;
     22 typedef long double LD;
     23 typedef pair<int,int> pii;
     24 typedef unsigned long long uLL;
     25 
     26 const int maxn = 1e5+2;
     27 const int INF  = 1<<30;
     28 const int mod  = 1e9+7;
     29 
     30 struct node
     31 {
     32     LL n,m,id;
     33 }s[maxn];
     34 LL ans[maxn],inv[maxn],fact[maxn];
     35 LL sq,tot;
     36 bool cmp(node a, node b){
     37     if(a.n/sq == b.n/sq) return a.m < b.m;
     38     return a.n/sq <b.n/sq;
     39 }
     40 LL qpow(LL x,LL y){
     41     LL res = 1;
     42     while(y){
     43         if(y&1)res = (LL)res*x*1ll%mod;
     44         x = x * x % mod;
     45         y >>= 1;
     46     }
     47     return res; 
     48 }
     49 void init(){
     50     fact[0] = 1;
     51     for(int i = 1;i < maxn;i++){
     52         fact[i] = fact[i-1]*i%mod;             // 预处理阶乘 
     53     }
     54     inv[maxn-1] = qpow(fact[maxn-1],mod-2);    // 预处理逆元
     55     for(int i=maxn-2;i>=0;i--){
     56         inv[i] = inv[i+1]*(i+1)%mod;
     57     }
     58 }
     59 
     60 LL C(LL n,LL m){                               // 组合数
     61     return (fact[n] * inv[m] %mod) * inv[n-m] % mod;
     62 }
     63 
     64 void solve(){
     65     int t; tot = 0;
     66     init();
     67     scanf("%d",&t);
     68     for(int i=1;i<=t;i++){
     69         scanf("%lld%lld",&s[i].n,&s[i].m);
     70         s[i].id = i; tot = max(tot,s[i].n); 
     71     }
     72     sq = sqrt(tot);
     73     sort(s+1,s+1+t,cmp);
     74     LL L=1,R=-1,res = 0;
     75     for(int i=1;i<=t;i++){                      // 莫队部分,每次进行状态转移
     76         while(L<s[i].n){res = ((2*res - C(L++,R))+mod)%mod;}
     77         while(L>s[i].n){res = ((res + C(--L,R))%mod*inv[2]%mod)%mod;}
     78         while(R<s[i].m){res = (res + C(L,++R))%mod;}
     79         while(R>s[i].m){res = (res - C(L,R--)+mod)%mod;}
     80         ans[s[i].id ] = res;
     81     }
     82     for(int i=1;i<=t;i++){
     83         printf("%lld
    ",ans[i]);
     84     }
     85     return;
     86 }
     87 
     88 int main()
     89 {
     90 //    freopen("in.txt","r",stdin);
     91 //    freopen("out.txt","w",stdout);
     92 //    ios::sync_with_stdio(false);
     93     int t = 1;
     94     //scanf("%d",&t);
     95     while(t--){
     96     //    printf("Case %d: ",cas++);
     97         solve();
     98     }
     99     return 0;
    100 }

    比赛时没有做出来,真的蒟蒻

     

  • 相关阅读:
    经典javascript
    大话prototype
    DataTable使用方法总结
    实验四 Web服务器1socket编程
    2.4 OpenEuler中C语言中的函数调用测试
    20191323王予涵第13章学习笔记
    20191323王予涵第十三章学习笔记
    2.5 OpenEuler 中C与汇编的混合编程
    个人贡献
    20191323王予涵第十二章学习笔记
  • 原文地址:https://www.cnblogs.com/windystreet/p/9415250.html
Copyright © 2020-2023  润新知