codeforces 181 div2 C&E

比赛没打,B题估计写不熟练,C题虽然赛后搞定了,但不是很熟练,比赛做坑定不行

这题正面思考会很吐,尤其是YYdp的话,就及其不可取了。从一个条件入手,就是数字之和为good数,由于n=10^6,所以good数,也就是所有excellent数的数字之后也不过就是2^1+2^2+2^3+..2^7<=2^8,才200多种,很少。枚举结果,由于数字不是a就是b,再加上题目限定条件,必须是n位,好了,方程组ax+by=sum(digit),x+y=n,x和y分别代表各种数字的个数。接下来求组合数C(n,x)%mod,这个要用到逆元。。。。其实这题不过就是个意识的问题,意识快,白送之。。。附代码:

#include <iostream>
#include <cstdio>

#define u 127
#define mod 1000000007  
#define ll __int64

using namespace std;

ll sum;

void extend(ll a0,ll b0,ll &x,ll &y)  
{  
    if (!b0)  
    {  
        x=1;y=0;  
    }  
    else  
    {  
        extend(b0,a0%b0,x,y);  
        ll temp=x;x=y;  
        y=temp-a0/b0*y;  
    }  
}  

int com(int n,int k)
{
    if (k>n-k) k=n-k;
    ll p=1,q=1,x,y;
    for (int i=1;i<=k;i++)
    {
        p=p*(n+1-i)%mod;
        q=(q*i)%mod;
    }
    extend(q,mod,x,y);
    x=(x+mod)%mod;
    ll res=(p*x)%mod;
    return (int)res;
}

void dfs(int value,int a,int b,int n)
{
    if (value>b*n) return;
    int s=value-a*n;
    if (s>=0&&s%(b-a)==0) sum=(sum+com(n,s/(b-a)))%mod;
    dfs(value*10+a,a,b,n);
    dfs(value*10+b,a,b,n);
}

int main()
{
    int n,a,b;
    cin>>a>>b>>n;
    sum=0;
    dfs(0,a,b,n);
    cout<<sum<<endl;
    return 0;
}


E.请教cxlove爱神的,主要是如何处理分母的各个质因子。普通的作法坑定超时,于是就把a数组中所有的绑定在一起,不一一计算a[i]!的质因子情况,用cnt[i]表示数组中有多少个数大于等于i。然后枚举每个10^7的质因数,按照a[i],a[i]^2,a[i]^m..逐次筛选。预处理完了之后,再二分。最小值是max(a[i]),最大值是sum(a[i]),特别提醒,再用max(a[i])时,最好不要直接写max(x,y)函数,这个函数不支持int64,附代码:

#include <iostream>
#include <cstdio>
#include <vector>

#define N 10000006
#define ll __int64
#define pb push_back

using namespace std;

ll cnt[N],a[N];
vector<ll>b,c;

int check(ll n)
{
    ll i,j,k,z;
    for (i=0;i<b.size();i++)
    {
        j=b[i];
        z=0;
        k=j;
        while (true)
        {
            z+=n/k;
            if (n/k>=j) k*=j;
            else break;
        }
        if (z<c[i]) return 0; 
    }
    return 1;
}

ll search(ll l,ll r)
{
    if (r-l<=1)
    {
        if (check(l)) return l;
        else return r;
    }
    ll m =(l+r)/2;
    if (check(m)) return search(l,m);
    else return search(m+1,r);
}

int main()
{
    ll n,x,t,i,j,k,mmax=-1,zs=0;
    cin>>n;
    for (i=1;i<=n;i++) 
    {
        cin>>x;
        cnt[x]++;
        if (x>mmax) mmax = x;
        zs+=x;
    }
    for (i=N-2;i>=1;i--) cnt[i]+=cnt[i+1];
    for (i=2;i<=mmax;i++)
        if (!a[i])
        {
            t=0;
            j=i;
            while (j<=mmax)
            {               
                for (k=j;k<=mmax;k+=j) 
                {
                    if (k!=i) a[k]=1;
                    t+=cnt[k];
                }
                if (mmax/j>=i) j*=i;
                else j=mmax+1;
            }
            b.pb(i);
            c.pb(t);
        }
    cout<<search(mmax,zs)<<endl;
    //system("pause");
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值