zoukankan      html  css  js  c++  java
  • CF1295E Permutation Separation

    我的blog

    题目链接:CF1295E Permutation Separation

    [preface ]

    本文版权归博客园,洛谷博客和蒟蒻wjr所有,欢迎转载,但需保留此段声明,并给出原文链接,如有侵权行为,还请不吝啬向博主举报,谢谢合作。

    开一波E题闷声发大财

    感谢@Karry5307 在考后提供思路

    [description ]

    给定一个序列(p)(为1~n的排列),和这个序列每一个数所对应的花费a以及序列的长度n。

    取一数(1leq k<n),将(p)序列分成两个序列,分别是(p_1,p_2,...,p_k)(p_{k+1},p_{k+2},...,p_n)

    将两个序列的某些数移到另一个序列使得第一个序列的所有数小于第二个序列的所有数,注意如果其中一组为空,则满足此条件,移动(p_i)的花费是(a_i)

    求最小花费

    [solution ]

    一道裸的线段树

    考虑维护(a_i)的前缀和(sum_i=sum_{j=1}^{i}a_i),因为(1leq k<n),所以前缀和(sum)最多只要维护到(a_{n-1})即可

    假设第一个序列的所有数都移到了第二个序列值最小虽然不大可能
    答案是(sum)中的最小值

    因为(p)序列是1~n的排列,所以记(pos_i)(i)在序列(p)中出现的位置

    枚举i从1~n

    假设将(p[pos_i])最终在第一序列,那么(p[pos_1],p[pos_2],...,,p[pos_{i-1}]一定在最终在第一序列),考虑当前对前缀和的修改。

    (k>=pos_i)时,(p[pos_i])在第一序列,那么不需要费用

    (k<pos_i)时,(p[pos_i])在第二序列,需要(a[pos_i])的费用移动到第一序列

    则将(sum_1)~(sum_{pos_i-1})的值分别加上(a[pos_i])

    (sum_{pos_i})~(sum_{n-1})的值分别减去(a[pos_i])

    当前策略最小值即当前(sum)的最小值。

    答案即是对所有策略的最小值取最小值

    [code ]

    #include <cstdio>
    #include <algorithm>
    #define re register
    #define ll long long
    #define lc (root<<1)
    #define rc (root<<1|1)
    using namespace std;
    template<typename T>
    inline void read(T&x)
    {
    	x=0;
    	char s=(char)getchar();
    	bool flag=false;
    	while(!(s>='0'&&s<='9'))
    	{
    		if(s=='-')
    			flag=true;
    		s=(char)getchar();
    	}
    	while(s>='0'&&s<='9')
    	{
    		x=(x<<1)+(x<<3)+s-'0';
    		s=(char)getchar();
    	}
    	if(flag)
    		x=(~x)+1;
    	return;
    }
    const int N=2e5+5;
    struct Tree
    {
    	ll minn,lazy;
    } tree[N<<2];
    ll sum[N];
    inline void build(int root,int l,int r)
    {
    	if(l==r)
    	{
    		tree[root].minn=sum[l];
    		tree[root].lazy=0;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(lc,l,mid);
    	build(rc,mid+1,r);
    	tree[root].minn=min(tree[lc].minn,tree[rc].minn);
    	return;
    }
    inline void pushdown(int root)
    {
    	if(!tree[root].lazy)
    		return;
    	tree[lc].minn+=tree[root].lazy;
    	tree[rc].minn+=tree[root].lazy;
    	tree[lc].lazy+=tree[root].lazy;
    	tree[rc].lazy+=tree[root].lazy;
    	tree[root].lazy=0;
    	return;
    }
    inline void change(int root,int l,int r,int x,int y,int val)
    {
    	if(r<x||l>y)
    		return;
    	if(x<=l&&r<=y)
    	{
    		tree[root].minn+=val;
    		tree[root].lazy+=val;
    		return;
    	}
    	int mid=(l+r)>>1;
    	pushdown(root);
    	change(lc,l,mid,x,y,val);
    	change(rc,mid+1,r,x,y,val);
    	tree[root].minn=min(tree[lc].minn,tree[rc].minn);
    	return;
    }
    int n,p[N],a[N],pos[N];
    ll ans;
    int main()
    {
    	read(n);
    	for(re int i=1; i<=n; ++i)
    	{
    		read(p[i]);
    		pos[p[i]]=i;
    	}
    	for(re int i=1; i<=n; ++i)
    	{
    		read(a[i]);
    		sum[i]=sum[i-1]+a[i];
    	}
    	build(1,1,n-1);
    	ans=tree[1].minn;
    	for(re int i=1; i<=n; ++i)
    	{
    		change(1,1,n-1,1,pos[i]-1,a[pos[i]]);
    		change(1,1,n-1,pos[i],n-1,-a[pos[i]]);
    //		printf("%d
    ",ans);
    		ans=min(ans,tree[1].minn);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    在 Delphi 下使用 DirectSound (8): IDirectSound8.DuplicateSoundBuffer() 与 IDirectSoundBuffer.GetStatus()
    在 Delphi 下使用 DirectSound (10): 测试合唱效果器 IDirectSoundFXChorus8
    在 Delphi 下使用 DirectSound (7): 播放资源文件中的 Wave 数据
    在 Delphi 下使用 DirectSound (13): 测试回声效果器 IDirectSoundFXEcho8
    The process could not execute 'sp_replcmds' on ‘Server Name’
    C盘空间用完竟然造成applicationHost.config文件内容为空
    推荐阅读20101018
    SQL Server 2008 R2作业中无法新建与修改步骤的问题
    ASP.NET中获取URL重写前的原始地址
    在.NET 4中用IIS部署WCF就这么简单
  • 原文地址:https://www.cnblogs.com/wangjunrui/p/12244238.html
Copyright © 2011-2022 走看看