[loj3367]装饼干

先考虑如何判定一个$y$是否可行——从高位开始,记录这一位所需要的$2^{i}$数量$t$,若$y$的这一位为1,则$t+=x$,之后分两类讨论:1.$tle a_{i}$,令$t=0$;2.$b>a_{i}$,令$t=2(t-a_{i})$,记比较之前的$t$为$b_{i}$,最终,我们需要让$b_{0}le a_{0}$

考虑dp,设$f[i]$表示仅考虑$y$的第$[i,k)$位,且满足$b_{i}le a_{i}$的$y$的数量,那么答案即为$f[0]$

枚举$j$表示上一个满足$b_{j}le a_{j}$的位置,那么要满足$forall j<k< i,b_{j}>a_{j}$且$b_{i}le a_{i}$

假设$y$的第$j-1$到$i$位依次为$p_{i},...,p_{j-1}$,则有$b_{k}=sum_{l=k}^{j-1}xp_{l}cdot 2^{l-k}-sum_{l=k+1}^{j-1}a_{l}cdot 2^{l-k}$,由于后者为常数,不妨记为$C_{k}$,则要求$forall j<k<i,sum_{l=k}^{j-1}xp_{l}cdot 2^{l-k}> frac{C_{k}+a_{k}}{x}$且$sum_{l=i}^{j-1}xp_{l}cdot 2^{l-i}le frac{C_{i}+a_{i}}{x}$

对于第一个条件,$sum_{l=i}^{j-1}p_{l}cdot 2^{l-i}$越大越容易实现,因此可以给出这个值的下限,第二个条件又给出了上限,上限-下限+1即为答案

有两个细节问题:1.$y$的位数不一定为$k$,因此要补0到60位;2.上限要对$2^{j-i}-1$取$min$,若下限>上限则不可能出现这种情况,即对0取max

这样暴力计算时间复杂度为$o(qk^{3})$,发现$C_{k}$与$i$无关,因此可以优化到$o(qk^{2})$

 1 #include "biscuits.h" 
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 #define ll long long
 5 int n;
 6 ll f[105];
 7 ll count_tastiness(ll x,vector<ll>a){
 8     while (a.size()<60)a.push_back(0);
 9     n=60;
10     memset(f,0,sizeof(f));
11     f[n]=1;
12     for(int i=n-1;i>=0;i--)
13         for(int j=i+1;j<=n;j++){
14             ll mn=0,mx=0;
15             for(int k=j-1;k>=i;k--){
16                 mx=mx*2+a[k];
17                 if (k>i)mn=max(mn,((mx/x+1)<<(k-i)));
18             }
19             f[i]+=f[j]*max(min(mx/x,(1LL<<j-i)-1)-mn+1,0LL);
20         }
21     return f[0];
22 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/13815516.html