HDU 6333

题意略。

思路:莫队算法。

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
const int maxn = 1e5 + 5;

struct node{
    int n,m,id;
    node(int a = 0,int b = 0,int c = 0){
        n = a,m = b,id = c;
    }
};

LL fac[maxn],inv[maxn],ans[maxn];
node store[maxn];
int unit;

bool cmp(const node& n1,const node& n2){
    if(n1.m / unit != n2.m / unit) return n1.m / unit < n2.m / unit;
    return n1.n < n2.n;
}
LL exgcd(LL a,LL b,LL& x,LL& y){
    if(a == 0 && b == 0) return -1;
    if(b == 0){
        x = 1,y = 0;
        return a;
    }
    LL d = exgcd(b,a % b,y,x);
    y -= a / b * x;
    return d;
}
LL rev(LL a,LL n){
    LL x,y;
    LL d = exgcd(a,n,x,y);
    if(d == 1) return (x % n + n) % n;
    else return -1;
}
void init_inv(){
    fac[0] = 1;
    for(LL i = 1;i < maxn;++i) fac[i] = fac[i - 1] * i % mod;
    inv[maxn - 1] = rev(fac[maxn - 1],mod);
    for(LL i = maxn - 2;i >= 0;--i){
        inv[i] = (i + 1) * inv[i + 1] % mod;
    }
}
LL C(LL a,LL b){
    LL m = a,n = b;
    return ((fac[n] * inv[m]) % mod * inv[n - m]) % mod;
}
LL qmod(LL a,LL n){
    LL ret = 1;
    while(n){
        if(n & 1) ret = ret * a % mod;
        a = a * a % mod;
        n = n>>1;
    }
    return ret;
}

int main(){
    int T;
    scanf("%d",&T);
    init_inv();
    int maxx = 0;
    for(int i = 0;i < T;++i){
        scanf("%d%d",&store[i].n,&store[i].m);
        maxx = max(store[i].n,maxx);
        store[i].id = i;
    }
    unit = 318;
    sort(store,store + T,cmp);
    int L = 0,R = 1;
    LL temp = 1;
    for(int i = 0;i < T;++i){
        //printf("store[%d].n == %d store[%d].m == %d\n",i,store[i].n,i,store[i].m);
        while(R < store[i].n){
            ++R;
            LL keep = temp;
            keep -= C(L,R - 1);
            keep += mod;
            if(keep > mod) keep -= mod;
            temp += keep;
            if(temp > mod) temp -= mod;
            //printf("temp == %lld\n",temp);
        }
        while(R > store[i].n){
            --R;
            temp += C(L,R);
            if(temp > mod) temp -= mod;
            temp *= inv[2];
            temp %= mod;
        }
        while(L < store[i].m){
            ++L;
            temp += C(L,R);
            if(temp > mod) temp -= mod;
        }
        while(L > store[i].m){
            temp -= C(L,R);
            temp = (temp + mod);
            if(temp > mod) temp -= mod;
            --L;
        }
        ans[store[i].id] = temp;
    }
    for(int i = 0;i < T;++i) printf("%lld\n",ans[i]);
    return 0;
}

 

posted @ 2018-08-01 21:02  温和的提比略  阅读(127)  评论(0编辑  收藏  举报