Jishou University Programming Contest 2019 (to reproduce the race) I funny funny tree fruit (Mo + inverse team to play table)

Links: https://ac.nowcoder.com/acm/contest/992/I
Source: Cattle-off network
Time limit: C / C ++ 1 second, 2 seconds languages other
space restrictions: C / C ++ 32768K, other languages 65536k
 64bit the IO the Format: LLD%

Title Description
 

n different funny fruit, fruit funny desirable not to take each, selecting one of the number of all programs, find the probability of selecting the number m of the fruit does not exceed embodiment funny. (Modulo 109 + 7)
Input Description:
The first line a positive integer T (T <= 10 ^ 5 ) followed by two integers each row line T n, m (0 <m < = n <= 10 ^ 5)
output description:
T lines, each line represents an integer answer.

Example 1
 
Enter
Copy
2
5 2
5 1
 
Output
Copy
500000004
687500005
 
Outline of Solution: It is clear overall program number 2 n- types, and the number of legitimate programs for C (n, 0) + C (n, 1) + ...... + C (n, m) species
Because of t group asked if violence every demand, the inevitable time-out.
We let S (n, m) = C (n, 0) + C (n, 1) + ...... + C (n, m), the answer is S (n-, m) / 2 n-
Since violence timeout, we consider off-line approach, we naturally think of Mo team, but to use the Mo team, we have to meet to get [L, R-1] and [L in at O ​​(1) time, R + 1] and [L-1, R] and [L + 1, R] answers.
First, look at the change of m, very S (n, m) = S (n, m-1) + C (n, m)
Then look at the change of n, since C (a, b) = C (a-1, b) + C (a-1, b-1), we can obtain S (n, m) = 2S (n- 1, m) -C (n-1, m)
And then directly on the Mo team just fine.
 
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=1e5+7;
int n,m,pos[N];
long long re[N],inv[N],fac[N];
struct node{
    int l,r,id;
}Q[N];
ll Ans=2,ans[N];
int L=1,R=1;
ll qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
bool cmp(node x,node y){
    if(pos[x.l]==pos[y.l]) return pos[x.r]<pos[y.r];
    return pos[x.l]<pos[y.l];
}
void init(int n){
    re[0] = inv[1] = fac[0] = 1;
    for(int i = 1;i <= n;++i) fac[i] = fac[i-1] * i % mod;
    for(int i = 2;i <= n;++i) inv[i] = (mod-mod/i)*inv[mod%i] % mod;
    for(int i = 1;i <= n;++i) re[i] = re[i-1] * inv[i] % mod;
}
long long C(int a,int b){
    if(a < 0||b>a) return 0;
    return fac[a]*re[b]%mod*re[a-b]%mod;
}
void addL(int l,intr) { 
    Ans = (Ans + C (r, l))% change; 
} 
Void Dell ( int l, int r) { 
    Ans = (Ans-C (r, l) mod +)% change; 
} 
Void ADDR ( int l, int r) { 
    Ans = ( 2 * Ans-C (r 1 , l) + mod)% change; 
} 
Void DELR ( int l, int r) { 
    Ans = (Ans + C (r 1 , l)) mod% * inv [ 2 ]% change; 
} 
Int main () { 
    init ( 100000);
    int t;
    scanf("%d",&t);
    int sz=sqrt(100000);
    for(int i=1;i<=100000;i++) pos[i]=(i-1)/sz+1;
    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);
    for(int i=1;i<=t;i++){
        while(L<Q[i].l){
            L++;
            addL(L,R);
        }
        while(L>Q[i].l){
            delL(L,R);
            L--;
        }
        while(R<Q[i].r){
            R++;
            addR(L,R);
        }
        while(R>Q[i].r){
            delR(L,R);
            R--;
        }
        ans[Q[i].id]=Ans*qpow(qpow(2,R),mod-2)%mod;
    }
    for(int i=1;i<=t;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zjl192628928/p/11260422.html
Recommended