hdu 6333 Problem B. Harvest of Apples(莫队 组合数)

 

 

 

题目连接     http://acm.hdu.edu.cn/showproblem.php?pid=6333

 

 

 

 

题目大意:

题意很简单, 不多说

 

 

 

 

分析;

T × N 超时, 莫队优化一下, 官方题解

hdu 6333 Problem B. Harvest of Apples(莫队 组合数)_第1张图片

 

 

 

 

AC代码:

 /*************************************************
       Author       :    NIYOUDUOGAO
       Last modified:	2018-08-02 12:42
       Email        :    [email protected]
       Filename     :	t.cpp
 *************************************************/
#include 
#define mset(a, x) memset(a, x, sizeof(a))
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
int pos[N * 2];
ll f[N * 2], inv[N * 2], fac[N * 2];
ll res = 1;
ll ans[N * 2];

struct node{
    ll n, m;
    int Index;
}Q[N * 2];

bool cmp1(node x, node y) {
	if (pos[x.n] == pos[y.n])
    	return x.m < y.m;
	return x.n < y.n;
}
void init() {
    f[0] = f[1] = fac[0] = fac[1] = inv[0] = inv[1] = 1;
    for (int i = 2; i < N; i++) {
        fac[i] = (fac[i - 1] * i) % mod;
        inv[i] = inv1(i);
        f[i] = f[i - 1] * inv[i] % mod;
    }
}

ll C(int x, int y) {
    return fac[x] * f[y] % mod * f[x - y] % mod;
}


void work1(int tn, int tm){
    res = (res + C(tn, tm)) % mod;
}
void work2(int tn, int tm) {
    res = (res - C(tn, tm) + mod) % mod;
}
void work3(int tn, int tm) {
    res = (2 * res % mod - C(tn, tm) + mod) % mod;
}
void work4(int tn, int tm) {
    res = (res + C(tn - 1, tm)) % mod * inv[2] % mod;
}


int main() {
    init();
    int t;
    scanf ("%d", &t);
    int div = (int) sqrt(t * 1.0); 
    for (int i = 1; i <= t; i++) {
        scanf ("%lld%lld", &Q[i].n, &Q[i].m);
        pos[i] = (i - 1) / div + 1;
        Q[i].Index = i;
    }
    sort(Q + 1, Q + t + 1, cmp1);
    int tn = 0, tm = 0;
    for (int i = 1; i <= t; i++) {
        while (tm < Q[i].m) {
            work1(tn, ++tm);
        }
        while (tm > Q[i].m) {
            work2(tn, tm--);
        }
        while (tn < Q[i].n) {
            work3(tn++, tm);
        }
        while (tn > Q[i].n) {
            work4(tn--, tm);
        }
        ans[Q[i].Index] = res;
    }
    for (int i = 1; i <= t; i++) {
        printf ("%lld\n", ans[i]);
    }
    
    return 0;
}

 

你可能感兴趣的:(HDU,莫队算法)