CF1295E. Permutation Separation(线段树+lazy标记)

E. Permutation Separation

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a permutation p1,p2,…,pnp1,p2,…,pn (an array where each integer from 11 to nn appears exactly once). The weight of the ii-th element of this permutation is aiai.

At first, you separate your permutation into two non-empty sets — prefix and suffix. More formally, the first set contains elements p1,p2,…,pkp1,p2,…,pk, the second — pk+1,pk+2,…,pnpk+1,pk+2,…,pn, where 1≤k<n1≤k<n.

After that, you may move elements between sets. The operation you are allowed to do is to choose some element of the first set and move it to the second set, or vice versa (move from the second set to the first). You have to pay aiai dollars to move the element pipi.

Your goal is to make it so that each element of the first set is less than each element of the second set. Note that if one of the sets is empty, this condition is met.

For example, if p=[3,1,2]p=[3,1,2] and a=[7,1,4]a=[7,1,4], then the optimal strategy is: separate pp into two parts [3,1][3,1] and [2][2] and then move the 22-element into first set (it costs 44). And if p=[3,5,1,6,2,4]p=[3,5,1,6,2,4], a=[9,1,9,9,1,9]a=[9,1,9,9,1,9], then the optimal strategy is: separate pp into two parts [3,5,1][3,5,1] and [6,2,4][6,2,4], and then move the 22-element into first set (it costs 11), and 55-element into second set (it also costs 11).

Calculate the minimum number of dollars you have to spend.

Input

The first line contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the length of permutation.

The second line contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤n1≤pi≤n). It's guaranteed that this sequence contains each element from 11 to nnexactly once.

The third line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109).

Output

Print one integer — the minimum number of dollars you have to spend.

Examples

input

Copy

3
3 1 2
7 1 4

output

Copy

4

input

Copy

4
2 4 1 3
5 9 8 3

output

Copy

3

input

Copy

6
3 5 1 6 2 4
9 1 9 9 1 9

output

Copy

2

 

线段树,求当某个点位分割点时,移动后以每个数为 前缀最大值时的  最小移动的代价。线段树维护区间最小值,注意前缀移动后为空集的情况。其实情况为每个点的代价为前缀和。lazy标记直接标在父节点,非左右节点,比较简洁。

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=998244353;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	void work() {
		int n=ni();
		int[] A=nia(n);
		long[] W=na(n);
		long[] sum=new long[n];
		for(int i=0;i<n;i++) {
			sum[A[i]]=W[i];
		}
		for(int i=1;i<n;i++) {
			sum[i]+=sum[i-1];
		}
		Node root=new Node();
		for(int i=0;i<n;i++) {
			update(root,0,n-1,i,i,sum[i]);
		}
		long ret=Long.MAX_VALUE;
		long s=0;
		for(int i=0;i<n-1;i++) {
			int node=A[i];
			long w=W[i];
			s+=w;//前缀空集
			update(root,0,n-1,node,n-1,-w);
			if(node!=0)update(root,0,n-1,0,node-1,w);
			ret=Math.min(ret, root.min);
			ret=Math.min(ret, s);
		}
		out.println(ret);
	}
	
	void u2(Node node,long v) {
		node.min+=v;
		node.lazy+=v;
	}
	void updatelazy(Node node) {
		u2(getLnode(node),node.lazy);
		u2(getRnode(node),node.lazy);
		node.lazy=0;
	}
	private void update(Node node, int l, int r, int s,int e,long v) {
		if(l>=s&&r<=e) {
			node.min+=v;
			node.lazy+=v;
			return;
		}
		updatelazy(node);
		int m=l+(r-l)/2;
		if(m>=s) {
			update(getLnode(node),l,m,s,e,v);
		}
		if(m+1<=e) {
			update(getRnode(node),m+1,r,s,e,v);
		}
		node.min=Math.min(getLnode(node).min,getRnode(node).min);//左右节点可能有lazy标记
	}

	private Node getLnode(Node node) {
		if(node.lnode==null)node.lnode=new Node();
		return node.lnode;
	}
	private Node getRnode(Node node) {
		if(node.rnode==null)node.rnode=new Node();
		return node.rnode;
	}
	class Node{
		Node lnode,rnode;
		long lazy;
		long min;
	}
	
	//input
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt()-1;//
		}
		return A;
	}
}	

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}


	public String next() 
	{
		while(st==null || !st.hasMoreElements())//回车,空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt() 
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值