Cod sursa(job #1709861)

Utilizator UNIBUC_Costan_Iordache_MagureanuGangster Teddy Bears Trio UNIBUC_Costan_Iordache_Magureanu Data 28 mai 2016 14:12:48
Problema Padure2 Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 1.59 kb
#include<cstdio>
#include<utility>
#include<algorithm>
#define N 1000
#define M 2000000
#define MOD 2000003
using namespace std;

int dp[N+1];
int fact[M+1];

pair<int,int> ciupi[N+1];

void euclid(int a, int b, int &x, int &y) {

     if (!b) {
          x = 1;
          y = 0;
          return;
     }

     int xa, ya;
     euclid(b, a % b, xa, ya);
     x = ya;
     y = xa - (a / b)*ya;

}

int invMod(int n, int mod) {

    int x, y;
    euclid(mod, n, x, y);

    while (y < 0)
        y += mod;
    y %= mod;

    return y;
}

int getCount(pair<int, int> c) {
    //comb(n+m-2,n-1)
    int n=c.first,m=c.second;

    int ans=(1LL*fact[n+m-2]*invMod((1LL*fact[n-1]*fact[m-1])%MOD,MOD))%MOD;

    return ans;
}

int main(){
    freopen ("padure2.in","r",stdin);
    freopen ("padure2.out","w",stdout);
    int n,m,c,i,j;

    scanf ("%d%d%d",&n,&m,&c);

    fact[0]=1;
    for(i=1;i<=M;i++){
        fact[i]=(1LL*i*fact[i-1])%MOD;
    }

    for(i=1;i<=c;i++)
        scanf ("%d%d",&ciupi[i].first,&ciupi[i].second);

    sort(ciupi+1,ciupi+c+1);

    for(i=1;i<=c;i++){
        dp[i]=getCount(ciupi[i]);
        for(j=1;j<i;j++)
            if (ciupi[j].second<=ciupi[i].second){
                dp[i]-=((1LL*dp[j]*getCount(make_pair(ciupi[i].first-ciupi[j].first+1,ciupi[i].second-ciupi[j].second+1)))%MOD);
                if (dp[i]<0) dp[i]+=MOD;
            }
    }

    int ans=getCount(make_pair(n,m));
    for(i=1;i<=c;i++){
        dp[i]=(1LL*dp[i]*getCount(make_pair(n-ciupi[i].first+1,m-ciupi[i].second+1)))%MOD;
        ans-=dp[i];
        if (ans<0) ans+=MOD;
    }

    printf ("%d",ans);
    return 0;
}