HDU 6333 (组合数求和公式+莫队)

HDU 6333 (组合数求和公式+莫队)题意:求C(n,0)+C(n,1)+C(n,2)+…+C(n,m),T组数据,1<=T,n,m<=1e5思路:设题目要求S(n,m),根据组合数推导出S(n,m)=S(n,m-1)+C(n,m),S(n

题意:
求C(n,0)+C(n,1)+C(n,2)+…+C(n,m),T组数据,1<=T,n,m<=1e5

思路:
设题目要求S(n,m),根据组合数推导出S(n,m)=S(n,m-1)+C(n,m),S(n,m)=2*S(n-1,m)-C(n-1,m)
然后通过莫队算法求出T个询问,复杂度O(Tsqrt(n))

代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <sstream>
#define pb push_back
#define X first
#define Y second
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pii pair<int,int>
#define qclear(a) while(!a.empty())a.pop();
#define lowbit(x) (x&-x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define mst(a,b) memset(a,b,sizeof(a))
#define cout3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
#define cout2(x,y) cout<<x<<" "<<y<<endl
#define cout1(x) cout<<x<<endl
#define IOS std::ios::sync_with_stdio(false)
#define SRAND srand((unsigned int)(time(0)))
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
using namespace std;
const double PI=acos(-1.0);
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
const double eps=1e-8;
const int maxn=100005;
const int maxm=3000005;

struct node {
    int l,r,id;
    bool operator < (const node &b)const {
        if(l/315==b.l/315)
            return r<b.r;
        return l<b.l;
    }
} reg[maxn];
int ans[maxn];
int fac[maxn];
int facinv[maxn];
int inv2;
int qpow(ll a,int b){
    ll res=1;
    while(b){
        if(b&1){
            res=res*a%mod;
        }
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
void init(){
    facinv[0]=fac[0]=1;
    for(int i=1;i<=1e5;i++){
        fac[i]=(ll)fac[i-1]*i%mod;
        facinv[i]=qpow(fac[i],mod-2);
    }
    inv2=qpow(2,mod-2);
}
int cal(int m,int n){
    return (ll)fac[n]*facinv[m]%mod*facinv[n-m]%mod;
}
void solve() {
    init();
    int t;
    sd(t);
    for(int i=1;i<=t;i++){
        sdd(reg[i].r,reg[i].l);
        reg[i].id=i;
    }
    sort(reg+1,reg+t+1);
    int l=0,r=0;
    ll nowans=1;
    for(int i=1; i<=t; i++) {
        while(r<reg[i].r) {
            nowans=(nowans*2%mod-cal(l,r)+mod)%mod;
            r++;
        }
        while(r>reg[i].r) {
            r--;
            nowans=((nowans+cal(l,r))%mod*inv2)%mod;
        }
        while(l<reg[i].l) {
            l++;
            nowans=(nowans+cal(l,r)+mod)%mod;
        }
        while(l>reg[i].l) {
            nowans=(nowans-cal(l,r)+mod)%mod;
            l--;
        }
        ans[reg[i].id]=nowans;
    }
    for(int i=1;i<=t;i++){
        printf("%d\n",ans[i]);
    }
    return ;
}
int main() {
#ifdef LOCAL
    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
#else
    //    freopen("","r",stdin);
    //    freopen("","w",stdout);
#endif
    solve();
    return 0;
}

 

今天的文章HDU 6333 (组合数求和公式+莫队)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/65983.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注