标签:include eof == sdi mat mod const lse 最小
化简一下题意:其实就是求:
\(\sum_{i = 1}^n [a0b1] + \sum_{i = 1}^n [a1b0]\)
其实就等于\(\sum_{i = 1}^n [a0b1] + \sum_{i = 1}^n[b0] - \sum_{i = 1}^n[a0b0]\),其实现在已经和\(a1\)没关系了,这里的\(b0\)也可以直接算出来。
接着我们想一个\(dp\),\(dp_i\)表示前\(i\)个数中\(a0b1 - a1b0\)的最小值。
我们把所有区间排个序,
然后考虑一下选与不选这个区间的情况,
因为选了都为\(1\),而现在已经和\(1\)没有关系了,所以可以理解为从\(i - 1 \sim j\)这里跳过来,取个最小值,这里可以用线段树来优化。
而不选其实就是\(dp[i - 1] + (!b[i] ? -1 : 1)\),因为前面推的\(dp\)的公式是\(a0b1 - a1b0\)。
然后就做完了,代码感觉挺好写的样子。
#include <bits/stdc++.h>
const int maxn = 2e5 + 10;
const int inf = 0x3f3f3f3f;
int n, m, i, j, k, cnt0, dp[maxn];
int a[maxn], b[maxn], t[maxn << 2];
std::vector<int> v[maxn];
inline int _max(int a,int b) { return a > b ? a : b; }
inline int _min(int a,int b) { return a < b ? a : b; }
inline void cmin(int& a,int b) {
if(a > b)
a = b;
}
template<class t> inline void read(t& res) {
res = 0; char ch = getchar(); bool sign = 0;
while(!isdigit(ch))
sign |= ch == '-', ch = getchar();
while(isdigit(ch))
res = (res << 1) + (res << 3) + (ch & 15), ch = getchar();
if(sign)
res = -res;
}
inline int f(int x) {
return x == 1 ? 1 : -1;
}
void build(int l,int r,int u) {
t[u] = inf;
if(l == r)
return;
int mid = (l + r) >> 1;
build(l,mid,u << 1);
build(mid + 1,r,u << 1 | 1);
}
inline void push_up(int u) {
t[u] = _min(t[u << 1],t[u << 1 | 1]);
}
void modify(int M,int l,int r,int u,int v) {
if(l == r)
return cmin(t[u],v), void();
int mid = (l + r) >> 1;
if(M <= mid)
modify(M,l,mid,u << 1,v);
else
modify(M,mid + 1,r,u << 1 | 1,v);
push_up(u);
}
int query(int ql,int qr,int l,int r,int u) {
if(ql <= l && r <= qr)
return t[u];
int res = inf, mid = (l + r) >> 1;
if(ql <= mid)
cmin(res,query(ql,qr,l,mid,u << 1));
if(mid < qr)
cmin(res,query(ql,qr,mid + 1,r,u << 1 | 1));
return res;
}
int main() {
read(n);
memset(dp,0x3f,sizeof(dp));
for(int i = 1;i <= n;i++)
read(b[i]), cnt0 += b[i] ^ 1;
build(1,n,1);
read(m);
for(int i = 1, l, r;i <= m;i++)
read(l), read(r), v[l].push_back(r);
dp[0] = 0;
for(int i = 1;i <= n;i++) {
int sz = v[i].size();
for(int j = 0;j < sz;j++) {
int x = v[i][j], mn = dp[i - 1];
cmin(mn, query(_max(i - 1,1),x,1,n,1));
if(mn < dp[x])
dp[x] = mn, modify(x,1,n,1,mn);
}
cmin(dp[i],dp[i - 1] + f(b[i]));
}
printf("%d",dp[n] + cnt0);
return 0;
}
标签:include eof == sdi mat mod const lse 最小
原文地址:https://www.cnblogs.com/Sai0511/p/11202625.html