Codeforces Round #313 (Div. 2) E. Gerald and Giant Chess theorem Lucas calculates the big composite number,

Source: Internet
Author: User

Codeforces Round #313 (Div. 2) E. Gerald and Giant Chess theorem Lucas calculates the big composite number,
E. Gerald and Giant Chesstime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard output

Giant chess is quite common in Geraldion. We will not delve into the rules of the game, we'll just say that the game takes place onHLimit × limitWField, and it is painted in two colors, but not like in chess. almost all cells of the field are white and only some of them are black. currently Gerald is finishing a game of giant chess against his friend Pollard. gerald has almost won, and the only thing he needs to win is to bring the pawn from the upper left corner of the board, where it is now standing, to the lower right corner. gerald is so Confident of Vicente that he became interested, in how many ways can he win?

The pawn, which Gerald has got left can go in two ways: one cell down or one cell to the right. in addition, it can not go to the black cells, otherwise the Gerald still loses. there are no other pawns or pieces left on the field, so that, according to the rules of giant chess Gerald moves his pawn until the game is over, and Pollard is just watching this process.

Input

The first line of the input contains three integers:H, Bytes,W, Bytes,N-The sides of the board and the number of black cells (1 ≤ upperH, Bytes,WLimit ≤ limit 105, limit 1 limit ≤ limitNLimit ≤ limit 2000 ).

NextNLines contain the description of black cells.I-Th of these lines contains numbersRI, Bytes,CI(1 digit ≤ DigitRILimit ≤ limitH, Memory 1 ≤ memoryCILimit ≤ limitW)-The number of the row and column ofI-Th cell.

It is guaranteed that the upper left and lower right cell are white and all cells in the description are distinct.

Output

Print a single line-the remainder of the number of ways to move Gerald's pawn from the upper left to the lower right corner modulo109 finished + Updated 7.

Sample test (s) input
3 4 22 22 3
Output
2
Input
100 100 315 1616 1599 88
Output
545732279
To give a grid of n * m, only some points are bad and cannot be taken. The number of solutions from to n and m is required.
Set dp [I] to the total number of solutions that reach the I-th bad point without passing through other bad points. Add a vertex (N-1 m-1), then dp [k] is the answer.
Strong state transition equation dp [I] = C [x [I] + y [I], x [I]) -sum (dp [j] * C (x [I]-x [j] + y [I]-y [j], x [I]-x [j]). j indicates that all the bad points before I, because dp [I] here are not passing through other bad points and there are no repeated paths, therefore, the answer is to subtract the path from the previous bad point to I.
Sort them first to obtain the order of each vertex. In this way, you can enumerate them from small to large when updating the status. The total complexity is o (k * k );
The remaining problem is that c (n, m) is required. Because n and m are very large, the method to calculate the number of combinations is n * m, which is too complex, that is, the complexity of recursive o (n) is too high. The Theorem Lucas is introduced here, which is a method specifically used to calculate a large composite number.
Lucas (n, m, p) = c (n % p, m % p) * Lucas (n/p, m/p, p) set aa = n % p, bb = m % p; here we can see that the large numbers of n and m are converted to relatively small aa, bb,
This formula uses n-n/p m-m/p to Solve the Problem recursively. Calculate c (aa, bb) and use the combination formula aa! /(Bb! * (Aa-bb )! ), Because Division exists here, bb is required! * (Aa-bb )! . The inverse of p in Euler's formula is pow_mod (a, P-2, p), that is, a ^ (P-2) % p;
Therefore, the entire formula is converted to ret = (ret * fac [a] * pow_mod (fac [B] * fac [a-B] % p, P-2, p) % p; in this way, we can solve the problem recursively.
In summary, although n and m are very small and only 10 ^ 5 can be solved without the lucas theorem, there may be a situation where n and m are very large, the number reaches 10 ^ 9, while MoD is very small and only 10 ^ 5. In this way, this lucas theorem can be used in real use, and MOD is required to be a prime number, that Euler's theorem applies because it is a prime number.
#define N 2050#define M 100005#define maxn 205#define MOD 1000000007int n,m,k,r,c;ll a[N],ta[M + M];pii p[N];ll pow_mod(ll a,ll n,ll p){    ll res = 1;    while(n){        if(n & 1){           res = (res * a)%p;        }        n = n>>1;        a = ( a * a ) % p;    }    return res;}ll Lucas(ll a,ll b,ll p){    ll res = 1;    while(a && b){        ll aa = a % p,bb = b % p;        if(aa < bb) return 0;        res = (((res * ta[aa]) % p ) * pow_mod(ta[bb] * ta[aa - bb] % p,p - 2,p)) % p;        a = a/p;b = b/p;    }    return res;}void init(){    ta[0] = 1;    for(int i = 1;i<M + M;i++){        ta[i] = (ta[i-1] * i) % MOD;    }}int main(){    init();    while(S2(n,m)!=EOF)    {        S(k);        FI(k){            S2(r,c);r--,c--;            p[i].first = r,p[i].second = c;        }        p[k].first = n-1;p[k].second = m-1;k++;        sort(p,p+k);        FI(k){            a[i] = Lucas(p[i].first + p[i].second,p[i].second,MOD);            FJ(i){                if(p[j].second <= p[i].second){                    a[i] -= ( a[j] * Lucas(p[i].first - p[j].first + p[i].second - p[j].second,p[i].first - p[j].first,MOD)) % MOD;                    a[i] = (a[i] + MOD)%MOD;                }            }        }        cout<<a[k-1]<<endl;    }    return 0;}

Method 2
We do not need the lucas theorem here. We can use preprocessing directly and the Euler's formula to find the inverse element,
#define N 2050#define M 100005#define maxn 205#define MOD 1000000007int n,m,k,r,c;ll a[N],ta[M + M];pii p[N];ll pow_mod(ll a,ll n,ll p){    ll res = 1;    while(n){        if(n & 1){           res = (res * a)%p;        }        n = n>>1;        a = ( a * a ) % p;    }    return res;}ll Lucas(ll a,ll b,ll p){    if(a < b) return 0;    return ta[a]* pow_mod(ta[b] * ta[a - b] % p,p - 2,p) % p;}void init(){    ta[0] = 1;    for(int i = 1;i<M + M;i++){        ta[i] = (ta[i-1] * i) % MOD;    }}int main(){    init();    while(S2(n,m)!=EOF)    {        S(k);        FI(k){            S2(r,c);r--,c--;            p[i].first = r,p[i].second = c;        }        p[k].first = n-1;p[k].second = m-1;k++;        sort(p,p+k);        FI(k){            a[i] = Lucas(p[i].first + p[i].second,p[i].second,MOD);            FJ(i){                if(p[j].second <= p[i].second){                    a[i] -= ( a[j] * Lucas(p[i].first - p[j].first + p[i].second - p[j].second,p[i].first - p[j].first,MOD)) % MOD;                    a[i] = (a[i] + MOD)%MOD;                }            }        }        cout<<a[k-1]<<endl;    }    return 0;}


Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.