zoukankan      html  css  js  c++  java
  • P1485 火枪打怪

    二分,对于能贡献到位置 (j) 的子弹,拆式子:

    [sum p-(i_x-j)^2 ]

    [sum p-i_x^2+2 imes i_x imes j-j^2 ]

    [tot imes(p-j^2)-sum i_x^2+2 imes j imessum i_x ]

    因为每次 check 贡献的范围是一样的,从后往前依次打死,差分维护最后定长区间中的子弹数量、威力值和、威力值平方和。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000005
    #define Min(x,y)((x)<(y)?x:y)
    #define For(i,x,y)for(i=x;i<=(y);i++)
    #define Down(i,x,y)for(i=x;i>=(y);i--)
    #define int long long
    int x[N],y[N],z[N],m[N],n,k;
    int read()
    {
    	int A;
    	bool K;
    	char C;
    	C=A=K=0;
    	while(C<'0'||C>'9')K|=C=='-',C=getchar();
    	while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
    	return(K?-A:A);
    }
    bool check(int p)
    {
    	int len=Min(sqrt(p),n),i,xx,yy,zz,tmp,res;
    	xx=yy=zz=res=0;
    	For(i,1,n<<1)x[i]=y[i]=z[i]=0;
    	Down(i,n,1)
    	{
    		tmp=m[i]-(xx*(p-i*i)-yy+(i*zz<<1));
    		xx-=x[i+len];
    		yy-=y[i+len];
    		zz-=z[i+len];
    		if(tmp<0)continue;
    		tmp=tmp/p+(tmp%p>0);
    		res+=tmp;
    		x[i]+=tmp;
    		xx+=x[i];
    		y[i]+=i*i*tmp;
    		yy+=y[i];
    		z[i]+=i*tmp;
    		zz+=z[i];
    		if(res>k)return 0;
    	}
    	return 1;
    }
    signed main()
    {
    	int i,l=1,r=10000000000000000ll,mid;
    	n=read(),k=read();
    	For(i,1,n)m[i]=read()+1;
    	while(l<r)
    	{
    		mid=(l+r)>>1;
    		if(check(mid))r=mid;
    		else l=mid+1;
    	}
    	cout<<l;
    	return 0;
    }
    
  • 相关阅读:
    Alpha版本发布说明
    团队作业week9
    Alpha版本发布时间安排
    2014年团队博客
    本周团队分数统计
    当前个人及团队分数统计
    团队作业week7
    Java FX入门
    Java第06次实验提纲(集合)
    Java第04次实验提纲(面向对象2-继承、多态、抽象类与接口)
  • 原文地址:https://www.cnblogs.com/May-2nd/p/14785237.html
Copyright © 2011-2022 走看看