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,m)=2*S(n-1,m)-C(n-1,m)
然后通过莫队算法求出T个询问,复杂度O(Tsqrt(n))

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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
#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<>=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(rreg[i].r) {
            r--;
            nowans=((nowans+cal(l,r))%mod*inv2)%mod;
        }
        while(lreg[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;
}

 

你可能感兴趣的:(ACM)