标签:月赛 int qry mid maxn ans 5125 bit Lydsy1712
很显然的dp式子
\(dp_i = dp_j + calc(j + 1,i)\)
然后发现这个 \(calc(i-1,j+1) + calc(i,j) \geq calc(i-1,j) + calc(i,j+1)\)
满足四边形不等式,然后就可以决策单调性,区间逆序对搞个莫队就完了。
#include <bits/stdc++.h>
using namespace std;
template <int maxn>
struct BIT {
int c[maxn];
int low(int x) { return x & -x; }
void add(int x, int y) {
for (; x < maxn; x += low(x)) c[x] += y;
}
int qry(int x) {
int ans = 0;
for (; x; x ^= low(x)) ans += c[x];
return ans;
}
};
int n, k;
const int maxn = 4e4 + 44;
BIT<maxn> bit;
int a[maxn], f[maxn], g[maxn];
int l, r, ans = 0;
void modify(int ql, int qr) {
while (l < ql) {
bit.add(a[l], -1);
ans -= bit.qry(a[l++] - 1);
}
while (l > ql) {
bit.add(a[--l], 1);
ans += bit.qry(a[l] - 1);
}
while (r < qr) {
bit.add(a[++r], 1);
ans += bit.qry(n) - bit.qry(a[r]);
}
while (r > qr) {
bit.add(a[r], -1);
ans -= bit.qry(n) - bit.qry(a[r--]);
}
}
void solve(int l, int r, int L, int R) {
if (l > r) return;
int mid = l + r >> 1, p;
for (int i = min(mid - 1, R); i >= L; --i) {
modify(i + 1, mid);
if (g[i] + ans < f[mid]) f[mid] = g[i] + ans, p = i;
}
solve(l, mid - 1, L, p);
solve(mid + 1, r, p, R);
}
signed main() {
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
l = 1, r = 0;
for (int i = 1; i <= n; i++) {
modify(1, i), f[i] = ans;
}
for (int i = 2; i <= k; i++) {
for (int j = 1; j <= n; j++) g[j] = f[j];
for (int j = 1; j <= n; j++) f[j] = 1e9;
solve(1, n, 1, n);
}
printf("%d\n", f[n]);
return 0;
}
标签:月赛,int,qry,mid,maxn,ans,5125,bit,Lydsy1712 来源: https://www.cnblogs.com/Isaunoya/p/12625825.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。