[Codeforces 1295E]Permutation Separation(线段树+贪心)
[Codeforces 1295E]Permutation Separation(线段树+贪心)
题面
给出一个排列p1,p2,...pn.初始时你需要选择一个位置把排列分成左右两个。然后在两个序列间移动元素使得左边序列的所有元素都比右边的所有元素小。给出每个元素pi从一个序列移动到另一个序列的代价ai.
分析
显然最后得到的序列是小的数在一边,大的数在另一边。设从值为i的元素处分开之后移动代价为ansi. 一开始假设所有数都移到右边序列,那么ansi就是值≤i的元素的代价之和。然后从1~n枚举分割点i。对于pi,它放到左边之后ans[pi+1,n]都需要去掉代价(因为pi一开始就在左边,不需要移动)ai.而ans[0,pi−1]需要增加代价ai.当前答案就是所有ans的最小值.
用线段树维护ans数组,时间复杂度为O(nlogn)
代码
#include<iostream> #include<cstdio> #include<cstring> #define INF 0x3f3f3f3f3f3f3f3f #define maxn 200000 using namespace std; typedef long long ll; struct segment_tree{ struct node{ int l; int r; ll val; ll mark; }tree[maxn*4+5]; void push_up(int pos){ tree[pos].val=min(tree[pos<<1].val,tree[pos<<1|1].val); } void build(int l,int r,int pos){ tree[pos].l=l; tree[pos].r=r; if(l==r) return; int mid=(l+r)>>1; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); } void add_tag(int pos,ll mark){ tree[pos].val+=mark; tree[pos].mark+=mark; } void push_down(int pos){ if(tree[pos].mark){ add_tag(pos<<1,tree[pos].mark); add_tag(pos<<1|1,tree[pos].mark); tree[pos].mark=0; } } void update(int L,int R,int val,int pos){ if(L<=tree[pos].l&&R>=tree[pos].r){ add_tag(pos,val); return; } push_down(pos); int mid=(tree[pos].l+tree[pos].r)>>1; if(L<=mid) update(L,R,val,pos<<1); if(R>mid) update(L,R,val,pos<<1|1); push_up(pos); } inline ll get_min(){ return tree[1].val; } }T; int n; int p[maxn+5],a[maxn+5]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&p[i]); } for(int i=1;i<=n;i++) scanf("%d",&a[i]); T.build(0,n,1);//线段树的区间[i,i]表示开始在值i位置分开的答案ans[i] for(int i=1;i<=n;i++){//一开始假设所有数都移到右边,那么ans[i]就是p的前缀和sum[i] T.update(p[i],n,a[i],1); } ll ans=INF; for(int i=1;i<n;i++){//贪心,把小的数放到左边,枚举哪些数要放 T.update(p[i],n,-a[i],1);//去掉p[i]从右到左的代价 T.update(0,p[i]-1,a[i],1); ans=min(ans,T.get_min()); } printf("%I64d\n",ans); }
版权声明:因为我是蒟蒻,所以请大佬和神犇们不要转载(有坑)的文章,并指出问题,谢谢
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· DeepSeek+PageAssist实现本地大模型联网
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· 从 14 秒到 1 秒:MySQL DDL 性能优化实战