CF319C (min 李超树 )

// LUOGU_RID: 130233533
#include 
using namespace std;
#define int long long
using ll=long long;
using ull=unsigned long long ;
#define vi vector<int>
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define inf 1ll << 62
#define ar(k) array<int,k>
#define db double
#define endl "\n"
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define de_bug(x) cerr << #x << "=" << x << endl
#define all(a) a.begin(), a.end()
#define IOS                         \
	std::ios::sync_with_stdio(false); \
	std::cin.tie(0);                       \
	std::cout.tie(0);
#define fer(i, a, b) for (int i = a; i <= b; i++)
#define der(i, a, b) for (int i = a; i >= b; i--)
const int mod = 998244353;
const int N = 1e6 + 10;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
int n, m, k;
int a[N],b[N],c[N];
int dp[N];
struct node {
	int k,b;
	node(int K=1e9,int B=1e15) :k(K),b(B) {}
#define ls i*2
#define rs i*2+1
} tr[N*4];
int  calc(node t,int x) {
	return t.k*x+t.b;
}
bool cover(node o,node n,int x) {
	return calc(o,x)>=calc(n,x);
}
void insert(int i,int l,int r,node t) {
	if(cover(tr[i],t,c[l] )&&cover(tr[i],t,c[r] )) {
		tr[i]=t;
		return ;
	}
	if(l==r)return ;
	int mid=l+r>>1;
	if(cover(tr[i],t,c[mid]))swap(tr[i],t);
	if(cover(tr[i],t,c[l] ))insert(ls,l,mid,t);
	if(cover(tr[i],t,c[r] ))insert(rs,mid+1,r,t);
}
int query(int i,int l,int r,int x) {
	int ans;
	if(l==r)return calc(tr[i],c[x] );
	int mid=l+r>>1;
	if(x<=mid) ans=query(ls,l,mid,x);
	else ans=query(rs,mid+1,r,x);
	return  min(ans,calc(tr[i],c[x]));
}
int d[N];
void solve() {
	cin >> n;
	int tot=0;
	for (int i = 1; i <= n; i ++) cin >> a[i], c[++ tot] = a[i];
	for (int i = 1; i <= n; i ++) cin >> b[i], c[++ tot] = b[i],d[i]=b[i];
	sort(c + 1, c + 1 + tot), tot = unique(c + 1, c + 1 + tot) - (c + 1);
	for (int i = 1; i <= n; i ++) {
		a[i] = upper_bound(c + 1, c + 1 + tot, a[i]) - (c + 1), b[i] = upper_bound(c + 1, c + 1 + tot, b[i]) - (c + 1);
	}
	insert(1, 1, tot, node(d[1], 0));
	for (int i = 2; i <= n; i ++) {
		dp[i] = query(1, 1, tot, a[i]);
		insert(1, 1, tot, node(d[i], dp[i]));
	}
	cout << dp[n];
}
signed main() {
	//freopen("../a.txt", "r", stdin);
	//freopen("../b.txt", "w", stdout);
	IOS;
	int _ = 1;
	// cin>>_;
	while (_--) solve();
	return 0;
}


你可能感兴趣的:(动态规划)