HDU6333 - 莫队算法

版权声明:本文为博主原创文章,未经博主允许不得转载,如需转载请注明出处。 https://blog.csdn.net/qq_36889101/article/details/81360037

Harvest of Apples

题目大意

给你n,m求 i = 0 m C n i % ( 10 9 + 7 )

数据范围

T组数据 T 10 5 , 1 m , n 10 5

解题思路

这题常规思路暴力求前缀和时间复杂度和空间复杂度都是显然不够的,所以,采用莫队算法将T个询问排序,之后将m看做l,n看做r,通过观察可以发现

i = 0 m C n i = 2 i = 0 m C n 1 i C n 1 m

所以首先将r加/减到指定行,之后对l进行加/减,设res为答案,即:

r加的时候: r e s = r e s 2 C r l , r + + ;

r减的时候: r , r e s = ( r e s + C r l ) / 2 ;

l加的时候: l + + , r e s = r e s + C r l ;

l减的时候: r e s = r e s C r l , l ;

具体见代码:

AC代码

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100000;
const int Pt = 1e9 + 7;
struct NOOD {
    int l, r, id;
}q[maxn + 5];
LL P[maxn + 5], rP[maxn + 5];
int T;
int B[maxn + 5];
LL qwe(LL x, LL y) {
    LL res = 1;
    while(y > 0) {
        if(y & 1)res = res * x % Pt;
        y >>= 1;
        x = x * x % Pt;
    }
    return res;
}
bool cmp(NOOD a, NOOD b) {
    if(B[a.l] == B[b.l])return a.r < b.r;
    else return a.l < b.l;
}
void Init() {
    P[0] = 1; rP[0] = qwe(P[0], Pt - 2);
    for(int i = 1; i <= maxn; i++) {
        P[i] = P[i - 1] * i % Pt;
        rP[i] = qwe(P[i], Pt - 2);
    }
    int unit = sqrt(maxn);
    for(int i = 1; i <= maxn; i++)B[i] = i / unit + 1;
    scanf("%d", &T);
    for(int i = 1; i <= T; i++)scanf("%d%d", &q[i].r, &q[i].l), q[i].id = i;
    sort(q + 1, q + T + 1, cmp);
}
LL C(int n, int m) {
    return P[n] * rP[n - m] % Pt * rP[m] % Pt;
}
vector<pair<int, LL> > ans;
int main() {
    LL res = 0;
    Init();
    int l = q[1].l, r = q[1].r;
    for(int i = 0; i <= l; i++)res = (res + C(r, i)) % Pt;
    ans.push_back(make_pair(q[1].id, res));
    for(int i = 2; i <= T; i++) {
        while(r < q[i].r) {
            res = ((res * 2 - C(r, l)) % Pt + Pt) % Pt;
            r++;
        }
        while(r > q[i].r) {
            r--;
            res = (res + C(r, l)) % Pt * rP[2] % Pt;
        }
        while(l < q[i].l) {
            l++;
            res = (res + C(r, l)) % Pt;
        }
        while(l > q[i].l) {
            res = ((res - C(r, l)) % Pt + Pt) % Pt;
            l--;
        }
        ans.push_back(make_pair(q[i].id, res));
    }
    sort(ans.begin(), ans.end());
    for(int i = 0; i < ans.size(); i++)printf("%lld\n", ans[i].second);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36889101/article/details/81360037