Codeforces Round #439 C

The Intriguing Obsession

题意:给出a、b、c 3种岛屿的个数,在岛屿之间连线,要求同种岛屿之间的最小距离大于等于3或者不可达,求方案数

思路:最短路只可能是3或者是不可达,画一下图即可知,任意2个不同的岛屿之间的连线与另一个岛屿无关,比如 a b之间的连线和c无关,a b之间可以在满足条件的情况下随便连,连完之后 b c之间同样可以在满足条件的情况下随便连,不需要考虑a的影响,因为a不会对他们造成影响,并且在2种岛屿之间,每一个岛屿最多连一条线,所以很明显了,只要单独两两考虑最后答案相乘即可

AC代码:

#include "iostream"
#include "iomanip"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#pragma comment(linker, "/STACK:102400000,102400000")
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("\n")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=998244353;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e5+100;

ll    exp_mod(ll a, ll b, ll p){
    ll res = 1;
    while(b != 0){
        if(b&1) res = (res * a) % p;
        a = (a*a) % p;
        b >>= 1;
    }
    return res;
}
ll Comb(ll a, ll b, ll p){
    if(a < b)   return 0;
    if(a == b)  return 1;
    if(b > a - b)   b = a - b;

    ll ans = 1, ca = 1, cb = 1;
    for(ll i = 0; i < b; ++i){
        ca = (ca * (a - i))%p;
        cb = (cb * (b - i))%p;
    }
    ans = (ca*exp_mod(cb, p - 2, p)) % p;
    return ans;
}
ll Lucas(ll n, ll m, ll p){
     ll ans = 1;
     while(n&&m&&ans){
        ans = (ans*Comb(n%p, m%p, p)) % p;
        n /= p;
        m /= p;
     }
     return ans;
}

ll A[5005]={1};
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll a,b,c, ans,ans1=0,ans2=0,ans3=0;
    cin>>a>>b>>c;
    for(int i=1; i<=5000; ++i) A[i]=(A[i-1]*i)%mod;
    for(int i=0; i<=min(a,b); ++i){
        ans1+=(((Lucas(a,i,mod)*Lucas(b,i,mod))%mod)*A[i])%mod;
        ans1%=mod;
    }
    for(int i=0; i<=min(a,c); ++i){
        ans2+=(((Lucas(a,i,mod)*Lucas(c,i,mod))%mod)*A[i])%mod;
        ans2%=mod;
    }
    for(int i=0; i<=min(b,c); ++i){
        ans3+=(((Lucas(b,i,mod)*Lucas(c,i,mod))%mod)*A[i])%mod;
        ans3%=mod;
    }
    ans=(((ans1*ans2)%mod)*ans3)%mod;
    cout<<ans<<endl;
    return 0;
}

 

posted on 2017-10-10 15:30  lazzzy  阅读(115)  评论(0编辑  收藏  举报

导航