• [BZOJ3835][POI2014]Supercomputer


    bzoj
    luogu

    description

    有一棵(n)个节点的树,有(q)次询问,每次给出一个(k),你需要用最少的操作次数选中树上的每一个点。每一次操作可以选中树上的至多(k)个点,但是要保证这些点的父亲都已经被选了(根一开始就可以选)。
    (n,qle10^6)

    sol

    考虑一下选择的过程。一开始瓶颈在于深度,一次操作可能选不满(k)个。当达到某个阈值时,瓶颈变为(k),即每次都可以选满(k)个点。
    我们可以枚举那个阈值(i),设(s_i)表示深度大于(i)的点的个数,那么(ans=max{i+lceilfrac{s_i}{k} ceil})。(所有的(i)中有且仅有一个(i)作为阈值是合法的,而不合法的情况都会把答案算小,所以就取(max)啦。)
    然后把(i)也放到上面去,得到(ans=max{lceilfrac{ik+s_i}{k} ceil})。实际上就是要最大化(ik+s_i)
    (k)视作自变量,那么我们就只需要维护直线(y=ix+s_i)构成的上凸壳就行了。
    复杂度(O(nlog n+qlog n))
    upt:突然意识到一个严重的问题,建凸壳为什么要带(log)???我一定是傻逼。
    但是我这带(log)跑得比(O(n))的快是什么鬼。

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    #define ll long long
    const int N = 1e6+5;
    int n,m,d,k[N],dep[N],s[N],top;
    struct node{int p,l,r;}q[N];
    ll cal(int p,int x){
    	return 1ll*p*x+s[p];
    }
    int binary(int x,int y){
    	int l=q[top].l,r=n,res=0;
    	while (l<=r){
    		int mid=l+r>>1;
    		if (cal(x,mid)<cal(y,mid)) res=mid,r=mid-1;
    		else l=mid+1;
    	}
    	return res;
    }
    int main(){
    	n=gi();m=gi();
    	for (int i=1;i<=m;++i) k[i]=gi();
    	for (int i=2;i<=n;++i) ++s[dep[i]=dep[gi()]+1],d=max(d,dep[i]+1);
    	for (int i=d;i;--i) s[i]+=s[i+1];
    	for (int i=1;i<=d;++i){
    		while (top&&cal(q[top].p,q[top].l)<cal(i,q[top].l)) --top;
    		if (!top) q[++top]=(node){i,1,n};
    		else{
    			int x=binary(q[top].p,i);
    			q[top].r=x-1;q[++top]=(node){i,x,n};
    		}
    
    	}
    	for (int i=1;i<=m;++i){
    		int l=1,r=top,res=0;
    		while (l<=r){
    			int mid=l+r>>1;
    			if (q[mid].l<=k[i]) res=mid,l=mid+1;
    			else r=mid-1;
    		}
    		printf("%lld ",(cal(q[res].p,k[i])+k[i]-1)/k[i]);
    	}
    	puts("");return 0;
    }
    
  • 相关阅读:
    软工第二次作业
    Internet: gmail on ubuntu
    English: assign
    Github: write blog by github
    Linux: left shift key not working on ubuntu18.04
    Using Doxygen to generate code documents
    Cpp: object lifetime
    Cpp: struct constructor
    Cpp: pass by reference
    HLS Stream Library
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9267403.html
Copyright © 2020-2023  润新知