zoukankan      html  css  js  c++  java
  • 【AT987】高橋君

    题目

    成爷爷一眼秒,(tql!!!)

    多组询问,求

    [sum_{i=0}^kC_{n}^i ]

    发现(k<=n)啊,于是我们可以把一组询问抽象成一个区间([k,n])

    左指针的移动非常好解决,就是加一下(C_n^k)减一下(C_n^k)就好了

    考虑一下右指针的移动,就是(n+1)或者(n-1)

    如果(n+1),就是从(sum_{i=0}^kC_n^i)变成了(sum_{i=0}^kC_{n+1}^i)

    我们利用组合数的小学生求法,拆开我们的柿子

    [sum_{i=0}^kC_{n+1}^i=sum_{i=0}^kC_{n}^i+C_{n}^{i-1}=2 imes sum_{i=0}^kC_{n}^i-C_n^k ]

    如果是(n-1),就是求

    [sum_{i=0}^kC_{n-1}^i=sum_{i=0}^kC_{n}^i-C_{n-1}^{i-1} ]

    也就是

    [2 imes sum_{i=0}^kC_{n-1}^i-C_{n-1}^k=sum_{i=0}^kC_{n}^i ]

    发现我们要求的东西都能从(sum_{i=0}^kC_n^i)(O(1))推过去

    于是莫队就没了

    成爷爷奇偶性排序(wa)了,这告诉我们拒绝玄学

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int maxn=1e5+5;
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    const LL mod=1e9+7;
    struct Ask{
    	int l,r,rk;
    }q[maxn];
    LL fac[maxn],inv[maxn],I2,ans;
    int Ans[maxn];
    int n,m,sz,L,R;
    inline int cmp(Ask A,Ask B) {
    	if(A.l/sz==B.l/sz) return A.r<B.r;
    	return A.l<B.l;
    }
    inline LL ksm(LL a,int b) {
    	LL S=1;
    	while(b) {if(b&1) S=S*a%mod;b>>=1;a=a*a%mod;}
    	return S;
    }
    inline LL C(int n,int m) {
    	if(n<m) return 0;
    	return fac[n]*inv[n-m]%mod*inv[m]%mod;
    }
    inline void add_(int x) {ans+=C(R,x);ans%=mod;}
    inline void del_(int x) {ans-=C(R,x);ans=(ans+mod)%mod;}
    inline void add(int x) {
    	ans=(ans*2ll)%mod;
    	ans=(ans-C(x-1,L)+mod)%mod;
    }
    inline void del(int x) {
    	ans=(ans+C(x-1,L))%mod;
    	ans=(ans*I2)%mod;
    }
    int main() {
    	m=read();
    	for(re int i=1;i<=m;i++) 
    		q[i].r=read(),q[i].l=read(),q[i].rk=i,n=max(n,q[i].r);
    	fac[0]=1;
    	for(re int i=1;i<=n;i++) 
    		fac[i]=(fac[i-1]*(LL)i)%mod;
    	inv[n]=ksm(fac[n],mod-2);
    	for(re int i=n-1;i>=0;--i) 
    		inv[i]=(inv[i+1]*(LL)(i+1))%mod;
    	sz=std::sqrt(n);
    	I2=ksm(2ll,mod-2);
    	L=1,R=1;ans=2;
    	std::sort(q+1,q+m+1,cmp);
    	for(re int i=1;i<=m;i++) {
    		while(R<q[i].r) add(++R);
    		while(L>q[i].l) del_(L--);
    		while(L<q[i].l) add_(++L);
    		while(R>q[i].r) del(R--);
    		Ans[q[i].rk]=ans;
    	}
    	for(re int i=1;i<=m;i++) printf("%d
    ",Ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    AngularJS $http模块POST请求
    thinkphp整合系列之融云即时通讯在线聊天
    Linux 常用命令
    Linux Shell脚本编写规范、例子
    Linux crontab定时执行任务 命令格式与详细例子
    Linux目录详细说明大全, 方便你以后合理规划及管理
    Linux 操作MySQL常用命令行
    SVN服务器搭建和使用(三)
    Linux下的SVN服务器搭建
    python 根据染色体起始终止点坐标来获取碱基序列
  • 原文地址:https://www.cnblogs.com/asuldb/p/10623281.html
Copyright © 2011-2022 走看看