bzoj1893&2371

9 篇文章 0 订阅
8 篇文章 0 订阅

2004年的论文《优化,再优化》
中所讨论的题的加强版(其实并没有加强多少……);
论文最后给出了 n 的复杂度;
其实可以用生成函数给出一种 logn 的做法,而且更加清晰;
首先有递推式:
g(i,j)=g(i1,j)+g(i1,j1)+1
g(1,j)=1
1<i,j
(可参考论文)
写成生成函数;
f1(x=11x1=x1x
fj(x)=(1+x)fj1(x)+x1x
解得: fjx)=(1+x)j1xx1x
再变回我们所熟悉的;
g(i,j)=Σjk=0Ckj1
然后就可以做啦.但细节一大堆(参考代码)…
其实这题本质上就是一个猜数问题是模型王子的弱化版;
只是条件弱化带来了更多性质;
最后很无耻的要到了数据…

#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=n;i++)
using namespace std;
typedef long long ll;
const ll lim=4294967296;
const int N=1e4+7;
const int M=100;
ll C[N][105];
int T,F,n,b;
void init(){
    C[0][0]=1;
    rep(i,1,N-1){
        C[i][0]=1;
        rep(j,1,M)C[i][j]=C[i-1][j-1]+C[i-1][j],C[i][j]=min(C[i][j],lim);
    }
    rep(i,1,N-1){
        rep(j,1,M)C[i][j]+=C[i][j-1],C[i][j]=min(C[i][j],lim);
    }
}
ll solve1(){
    if(n<N){
        if(b>M || C[n][b]>=lim)return -1;
        return C[n][b]-1;
    }
    else{
        if(b==1)return n;
        else if(b==2){
            ll ans=(1ll*n*n+1ll*n)/2ll;
            if(ans>lim)return -1;
            return ans;
        }else return -1;
    }
}
int solve2(){
    if(F>=N){
        if(b==1)return F;
        else if(b==2){
            int l=1,r=F;
            while(l<r){
                int x=(l+r)>>1;
                if(1ll*x*x+1ll*x<2ll*F)l=x+1;
                else r=x;
            }
            return l;
        }
    }
    rep(i,1,N-1)if(C[i][min(i,b)]-1>=F)return i;
    return -1;
}
int solve3(){
    if(n<N){
        rep(i,1,b)if(C[n][i]-1>=F)return i;
        return -1;
    }else{
        if(n>=F-1)return 1;
        else if(1ll*n*n+1ll*n-2ll>=2ll*F)return 2;
        else return 3;
    }
}
int main(){
    init();
    scanf("%d",&T);
    rep(t,1,T){
        scanf("%d%d%d",&F,&n,&b);b=min(b,n);
        printf("Case #%d: %lld %d %d\n",t,solve1(),solve2(),solve3());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值