传送门

文章目录

  • 题意:
  • 思路:

题意:

给你一个打乱的排列,每个位置都各有一个价值,让你选择一个分界点,分成p1,p2,...,prp_1,p_2,...,p_rp1​,p2​,...,pr​和pr+1,...,pn−1,pnp_{r+1},...,p_{n-1},p_{n}pr+1​,...,pn−1​,pn​,两部分非空,可以将某一边的数花费代价aia_iai​移动到另一边,当左边所有数都小于右边或者某一边为空的时候,符合条件,求符合条件的时候的最小代价。

思路:

先考虑暴力怎么写。
定义f[i][j]f[i][j]f[i][j]表示以iii为分割点,[1,i][1,i][1,i]在左边,[i+1,n][i+1,n][i+1,n]在右边,让后通过移动使得a[1,i]<=j,a[i+1,n]>ja_{[1,i]}<=j,a_{[i+1,n]}>ja[1,i]​<=j,a[i+1,n]​>j的最小代价是f[i][j]f[i][j]f[i][j],初始状态f[0][k]=∑i=1kbif[0][k]=\sum _{i=1}^{k}b_if[0][k]=∑i=1k​bi​(注意bbb是排序后iii这个位置的花费),转移也比较好写了:f[i][k]=f[i−1][k]−a[i]k∈[p[i],n]f[i][k]=f[i-1][k]-a[i] \ \ k\in [p[i],n]f[i][k]=f[i−1][k]−a[i]  k∈[p[i],n]f[i][k]=f[i−1][k]+a[i]k∈[1,p[i]−1]f[i][k]=f[i-1][k]+a[i] \ \ k\in [1,p[i]-1]f[i][k]=f[i−1][k]+a[i]  k∈[1,p[i]−1]
对于第一个方程的解释为当k∈[p[i],n]k\in [p[i],n]k∈[p[i],n]的时候,原本iii需要花费a[i]a[i]a[i]移动到左边,但是由于分割点右移,所以不需要花费a[i]a[i]a[i],所以应该减掉。
对于第二个方程解释为当k∈[1,p[i]−1]k\in [1,p[i]-1]k∈[1,p[i]−1]的时候,原本iii不需要花费a[i]a[i]a[i]到右边,因为本来就在右边,但是分割点右移之后他到左边了,所以需要花费a[i]a[i]a[i],应该加上。
但是这个方程的转移是O(N2)O(N^2)O(N2)的,我们考虑用线段树来实现区间加,让后维护一个minminmin,最后直接取tr[1].mintr[1].mintr[1].min即可。

//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n;
int p[N],a[N];
struct Tree
{struct Node{int l,r;LL mi,lazy;}tr[N<<2];void pushup(int u){tr[u].mi=min(tr[L].mi,tr[R].mi);}void pushdown(int u){if(tr[u].lazy==0) return;LL lazy=tr[u].lazy; tr[u].lazy=0;tr[L].lazy+=lazy; tr[L].mi+=lazy;tr[R].lazy+=lazy; tr[R].mi+=lazy;}void build(int u,int l,int r){tr[u]={l,r,0,0};if(l==r) { tr[u].mi=0; return; }build(L,l,Mid); build(R,Mid+1,r);}void modify(int u,int l,int r,int x){if(tr[u].l>=l&&tr[u].r<=r){tr[u].mi+=x;tr[u].lazy+=x;return;}pushdown(u);if(l<=Mid) modify(L,l,r,x);if(r>Mid) modify(R,l,r,x);pushup(u);}
}x;int main()
{//  ios::sync_with_stdio(false);
//  cin.tie(0);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]);LL ans=min(a[1],a[n]);x.build(1,1,n);for(int i=1;i<=n;i++) x.modify(1,p[i],n,a[i]);for(int i=1;i<=n-1;i++){x.modify(1,1,p[i]-1,a[i]);x.modify(1,p[i],n,-a[i]);ans=min(ans,x.tr[1].mi);}printf("%lld\n",ans);return 0;
}

Educational Codeforces Round 81 (Rated for Div. 2) E. Permutation Separation 线段树 + dp相关推荐

  1. Educational Codeforces Round 67 (Rated for Div. 2)(D思维题 线段树/E树形dp(换根dp) 二次扫描与换根法)

    心得 D写了个假算法被hack了wtcl- E据涛神说是二次扫描与换根法,看了看好像和树形dp差不多 F概率dp G费用流 回头再补 思路来源 马老师 归神 贤神等代码 http://www.mami ...

  2. Educational Codeforces Round 72 (Rated for Div. 2) D. Coloring Edges dfs树/拓扑找环

    传送门 文章目录 题意: 思路: 题意: 给你一张图,你需要给这个图的边染色,保证如果有环那么这个环内边的颜色不全相同,输出染色方案和用的颜色个数. n,m≤5e3n,m\le5e3n,m≤5e3 思 ...

  3. Educational Codeforces Round 111 (Rated for Div. 2) E. Stringforces 二分 + 状压dp

    传送门 文章目录 题意: 思路: 题意: 给你一个串,只包含前kkk个字母和???,定义fif_ifi​表示第iii个字母在串中出现的最长连续长度,你现在需要将???替换为前kkk个字母,使得mini ...

  4. Educational Codeforces Round 73 (Rated for Div. 2) Make The Fence Great Again dp + 结论

    传送门 文章目录 题意: 思路: 题意: 思路: 首先证明一个结论:一个数最多被加两次. 首先假设a[i]=a[i−1]a[i]=a[i-1]a[i]=a[i−1]或a[i]=a[i+1]a[i]=a ...

  5. Educational Codeforces Round 81 (Rated for Div. 2) F.Good Contest \ 洛谷 划艇 组合 计数dp

    cf传送门 P3643 [APIO2016]划艇 文章目录 题意: 思路: 题意: aia_iai​在[li,ri][l_i,r_i][li​,ri​]等概率随机选一个数,求aaa数组不增的概率. 思 ...

  6. Educational Codeforces Round 81 (Rated for Div. 2) C. Obtain The String 序列自动机

    传送门 文章目录 题意: 思路: 题意: 给你两个串s,ts,ts,t,每次可以取sss串的一个子序列,问你最少取多少次子序列,将这些子序列拼起来能得到ttt. 思路: 发现我题解里面没写过序列自动机 ...

  7. Educational Codeforces Round 81 (Rated for Div. 2) B. Infinite Prefixes 数学

    传送门 文章目录 题意: 思路: 题意: 给你个串sss,让后把它重复无限次得到ttt,定义前缀的价值为cnt0−cnt1cnt_0-cnt_1cnt0​−cnt1​,求ttt的前缀价值为xxx的前缀 ...

  8. Educational Codeforces Round 81 (Rated for Div. 2) D. Same GCDs 欧拉函数\莫比乌斯

    传送门 文章目录 题意: 思路: 题意: 给定a,ma,ma,m,求满足gcd(a,m)=gcd(a+x,m)gcd(a,m)=gcd(a+x,m)gcd(a,m)=gcd(a+x,m)的xxx的个数 ...

  9. Educational Codeforces Round 81 (Rated for Div. 2)

    A题: 我们贪心按照位数大的拼就可以了. #include <bits/stdc++.h> using namespace std; int t,n; int main() {scanf( ...

最新文章

  1. 用ZipInputStream和ZipOutputStream实现文件及文件夹的压缩解压
  2. Ubuntu 14.04 安装 Sublime Text 3
  3. Angel Borja博士教你如何撰写科学论文一:Six things to do before writing your manuscript
  4. Python数据结构学习笔记——搜索与排序算法
  5. with语句python_Python之with语句
  6. IIC驱动5150遇到麻烦
  7. 场景模型驱动自动化测试在盒马的探索及实践
  8. docker 随笔记录
  9. python有趣小程序-小码王分享python一些有趣的小程序
  10. Iphone 开发常用代码
  11. html 车牌号输入代码,html中车牌号省份简称输入键盘的示例代码(3)
  12. python字典存储数据的形式_python字典的常用操作,数据类型划分
  13. linux在当前目录 查找abc文件夹,《find技巧》-“linux命令五分系列”之一
  14. 腾讯云 接口验签 使用qcloud-java-sdk
  15. 值钱的木头——前缀和思想
  16. 推荐一个 Github 上最全的C语言教学
  17. Exp6 信息搜集与漏洞扫描 20164323段钊阳
  18. PTA7-31藏尾诗
  19. 深入学习VMware vSphere---基础知识
  20. 快看,他纯用css绘制出了嫦娥手捧的月兔,关键还能飞,牛

热门文章

  1. 从抛硬币试验看随机游走定义的基本概念错误
  2. 公交车座椅上有个洞,竟是为了…很多人都不知道
  3. 今年不容易,要懂得爱护自己
  4. 孩子不是笨,他和“最强大脑”差的是这个!
  5. 不懂这25个名词,好意思说你懂大数据?
  6. SVM支持向量机绘图
  7. oracle死锁解决常用方法(屡试不爽)
  8. shell grep 变量_老司机给出的关于 shell 脚本的8个建议,必收!
  9. php定位和天气,基于thinkphp实现依据用户ip判断地理位置并提供对应天气信息的应用...
  10. 华为交换机linux版本号,Cisco和华为交换机常用配置命令总结