2014-2015 ACM-ICPC, Asia Xian Regional Contest 6一些题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lingzidong/article/details/84312118

A - Built with Qinghuai and Ari Factor
这题面真的黑出翔,判断一个数列是不是全部是3的倍数
K - Last Defence
这道题稍微模拟一下就发现和辗转相除法很相似,如果A>B,那么肯定会减A/B次,这期间会产生这么多的不同的数,递归一下就行。

#include <bits/stdc++.h>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
ll gcd(ll a,ll b)
{
    if(b==0)return 1ll;
    if(a<b)
        swap(a,b);
    return (a/b)+gcd(b,a%b);
}
int main()
{
    //freopen("input.txt","r",stdin);
    int T;
    scanf("%d",&T);
    ll a,b;
    for(int cas=1; cas<=T; cas++)
    {
        scanf("%lld%lld",&a,&b);
        if(a==0 && b==0)
            printf("Case #%d: %lld\n",cas,1ll);
        else
            if(a==0 || b==0)
            printf("Case #%d: %lld\n",cas,2ll);
//        if(a>b)swap(a,b);
//        if(b%a==0)
//            printf("Case #%d: %lld\n",cas,b/a+1);
//        else
else
        {
            printf("Case #%d: %lld\n",cas,gcd(a,b));
        }
    }



    return 0;
}

F - Color
打表的时候发现可以容斥,首先要从m个颜色选k个,然后考虑这个系数放到一边。
现在指定了k个颜色,所有使用小于等于k的情况数就是
k ( k 1 ) n 1 k(k-1)^{n-1} ,然后我们把不等于k的容斥掉。对于任意一个小于k的情况i,相当于再从k种选i种,一加一减就容斥掉了。

#include <bits/stdc++.h>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
const ll mod = 1000000007;
ll pow_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 0ll;
    if(a==b) return 1ll;
    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*pow_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 calc(ll n,ll m,ll k)
{
    ll ans1=k*pow_mod(k-1,n-1,mod)%mod;
    return ans1 % mod;
}
int main()
{
    int t;
    scanf("%d",&t);
    ll n,m,k;
    int ca=1;
   // init(1000000);
    while(t--)
    {
        scanf("%I64d%I64d%I64d",&n,&m,&k);
        ll ans = 0;
        int sw = 1;
        ll com = 1LL;
        for(ll i = k;i>=1;i--)
        {
            if(sw)
                ans = (ans + (com*calc(n,m,i)% mod))% mod;
            else
                ans = (ans - (com*calc(n,m,i) % mod ) +mod) % mod;
            com = com*i%mod;
            com= ((com*pow_mod(k-i+1LL,mod-2LL,mod))%mod)% mod;
           // cout<<ans<<endl;
            sw ^= 1;
        }
        ans=ans*Comb(m,k,mod)%mod;
        printf("Case #%d: %I64d\n",ca++,ans);
//        cout<<ans<<' '<<Comb(m,k-1,mod)<<' '<<calc(k,n)<<' '<<calc(k-1,n)<<endl;
//        cout<<calc(k,n)<<' '<<(k-1,n)<<endl;

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lingzidong/article/details/84312118