zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    语句
    1101 事务存储引擎触发器函数
    1029 作业
    1029 数据库表以及行的基本操作
    1023 笔记
    1022 作业
    1022 笔记
    1021 笔记
    查看pip已经安装过的包
    查看Python支持的.whl文件版本
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13815516.html
Copyright © 2011-2022 走看看