zoukankan      html  css  js  c++  java
  • BZOJ4446: [Scoi2015]小凸玩密室

    用ui,j表示走完i的子树后走到i的深度为j的祖先的兄弟的最小代价;

    用vi,j表示走完i的子树后走到i的深度为j的祖先的最小代价,用u算出v。

    枚举起点,计算答案。

    #include<algorithm>
    #include<cstdio>
    using std::min;
    typedef long long ll;
    const int N=2e5+5;
    ll a[N],b[N],c[N],f[N][19][2];
    int main(){
    	struct{
    		operator int(){
    			int x=0,c=getchar();
    			while(c<48)c=getchar();
    			while(c>47)
    				x=x*10+c-48,c=getchar();
    			return x;
    		}
    	}it;
    	int n=it;
    	for(int i=1;i<=n;++i)
    		a[i]=it;
    	for(int i=2;i<=n;++i){
    		b[i]=it;
    		c[i]=c[i>>1]+b[i];
    	}
    	for(int i=n;i;--i)
    		for(int j=1;i>>j-1;++j)
    			if(i<<1>n){
    				f[i][j][0]=(c[i]-c[i>>j]+b[i>>j-1^1])*a[i>>j-1^1];
    				f[i][j][1]=(c[i]-c[i>>j])*a[i>>j];
    			}else{
    				f[i][j][0]=i<<1<n?min(b[i<<1]*a[i<<1]+f[i<<1][1][0]+f[i<<1^1][j+1][0],b[i<<1^1]*a[i<<1^1]+f[i<<1^1][1][0]+f[i<<1][j+1][0]):b[i<<1]*a[i<<1]+f[i<<1][j+1][0];
    				f[i][j][1]=i<<1<n?min(b[i<<1]*a[i<<1]+f[i<<1][1][0]+f[i<<1^1][j+1][1],b[i<<1^1]*a[i<<1^1]+f[i<<1^1][1][0]+f[i<<1][j+1][1]):b[i<<1]*a[i<<1]+f[i<<1][j+1][1];
    			}
    	if(~n&1)
    		f[n^1][2][1]=b[n>>1]*a[n>>2];
    	ll z=1e18;
    	for(int i=n;i;--i){
    		ll s=f[i][1][1];
    		for(int j=i;j>>1;j>>=1)
    			s+=b[j^1]*a[j^1]+f[j^1][2][1];
    		z=min(z,s);
    	}
    	printf("%lld
    ",z);
    }
    
  • 相关阅读:
    使用ansible 批量分发ssh密钥
    修改DNS
    如何使用openssl生成RSA公钥和私钥对
    压力测试 php-fpm 优化
    mysql 安装
    svn 权限配置
    powerdesigner导出word
    Mysql无法创建外键的原因
    office project 激活
    MySQL日志恢复误删记录
  • 原文地址:https://www.cnblogs.com/f321dd/p/5496296.html
Copyright © 2011-2022 走看看