zoukankan      html  css  js  c++  java
  • 洛谷 1485 火枪打怪

    Description

    LXL进入到了一片丛林,结果他发现有n只怪物排成一排站在他面前。LXL有一杆火枪能对付这些怪物。他知道从左至右数第i只怪物的血量是mi。现在LXL可以将一些子弹射向某个怪物。LXL可以控制他所发射的子弹数量及子弹的威力值。当某个子弹射到第i个怪物,如果这个子弹的威力值为p,除了这个怪物会掉p点血以外,它左边的第j个怪物(j<i),也会遭到Max(0, p - (i - j) * (i - j))的溅射伤害(好神奇的子弹)。当某只怪物的血量小于0时,它就死了,但它的尸体还在,即怪物的位置永远不会改变。LXL希望只用k发子弹,请你求出一个最小的正整数p,使LXL用k发子弹且每发子弹的威力值为p就可以消灭所有怪物。

    solution

    **正解:二分答案
    朴素做法从后往前扫,因为右边的点不能依赖左边的点的溅射伤害,所以如果还剩下血量必须得打掉,然后计算对左边的溅射伤害,计算溅射伤害是 (sqrt(n)) 的,考虑优化这个地方,伤害的式子是 $$p-(i-j)^2$$

    [p-(i^2-2*i*j+j^2) ]

    拆开之后非常好维护,这是一个 移动一个(sqrt(n)) 的窗口的过程,我们只需要维护窗口中的数的数量和 (j^2)(j) 的和即可,可以 (O(1)) 求出当前剩余的血量**

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<queue>
    #define RG register
    #define il inline
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define Max(a,b) ((a)>(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=500005;
    int n,K;ll a[N],c[N];
    il bool check(ll mid){
        ll tmp,ret=0,xy;
        RG int i;
       memset(c,0,sizeof(c));
       int block=sqrt(mid)+1;
       ll xif=0,cnt=0,xi=0;
       for(i=n;i>=1;i--){
          if(i+block<=n && c[i+block]>0){
             tmp=i+block;
             xif-=c[tmp]*tmp*tmp;
             cnt-=c[tmp];
             xi-=c[tmp]*tmp;
          }
          tmp=mid*cnt-cnt*i*i+2*xi*i-xif;
          tmp=a[i]-tmp;
          if(tmp>0){
             xy=(tmp+mid-1)/mid;
             xif+=xy*i*i;
             xi+=xy*i;
             cnt+=xy;
             ret+=xy;
             c[i]=xy;
          }
          if(ret>K)return 0;
       }
        return ret<=K;
    }
    
    void work()
    {
        ll l=1,r=2e14,mid,ans=0;
        scanf("%d%d",&n,&K);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]++;
        while(l<=r){
            mid=(l+r)>>1;
            if(check(mid))ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%lld
    ",ans);
    }
    
    int main()
    {
      work();
      return 0;
    }
    
    
  • 相关阅读:
    java积累
    J2SE J2EE J2ME的区别
    php无刷新上传图片
    C++小例子
    交通银行万事达Y-POWER信用卡 普卡
    代码面试最常用的5大算法
    php 读取 word
    PHP Simple HTML DOM 使用
    curl http认证
    PHP PDO 安装使用
  • 原文地址:https://www.cnblogs.com/Hxymmm/p/7767915.html
Copyright © 2011-2022 走看看