您的位置:首页 > 其它

bzoj1893&2371

2016-11-27 19:10 330 查看
2004年的论文《优化,再优化》

中所讨论的题的加强版(其实并没有加强多少……);

论文最后给出了n−√的复杂度;

其实可以用生成函数给出一种logn的做法,而且更加清晰;

首先有递推式:

g(i,j)=g(i−1,j)+g(i−1,j−1)+1

g(1,j)=1

1<i,j

(可参考论文)

写成生成函数;

f1(x)=11−x−1=x1−x

fj(x)=(1+x)fj−1(x)+x1−x

解得:fj(x)=(1+x)j1−x−x1−x

再变回我们所熟悉的;

g(i,j)=Σjk=0Ckj−1

然后就可以做啦.但细节一大堆(参考代码)…

其实这题本质上就是一个猜数问题是模型王子的弱化版;

只是条件弱化带来了更多性质;

最后很无耻的要到了数据…

#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
[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
[b]>=lim)return -1;
return C
[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
[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());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  生成函数 乱搞 数学