bzoj3675: [Apio2014]序列分割
留坑
为什么别人家的斜率优化跟我一点都不一样!
为什么斜率都要变成正的。。。
为什么要那么推式子
为什么不能直接做啊。。。。。
为什么不把0去掉去秒WA啊
为什么叉积去了0也过不了啊
woc啊
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<iostream> 6 7 using namespace std; 8 9 void setIO(const string& s) { 10 freopen((s + ".in").c_str(), "r", stdin); 11 freopen((s + ".out").c_str(), "w", stdout); 12 } 13 template<typename Q> Q read(Q& x) { 14 static char c, f; 15 for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1; 16 for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0'; 17 if(f) x = -x; 18 return x; 19 } 20 template<typename Q> Q read() { 21 static Q x; read(x); return x; 22 } 23 24 typedef long long LL; 25 const int N = 100000 + 10; 26 27 LL sqr(const LL& x) { 28 return x * x; 29 } 30 31 LL f[N], g[N], sum[N]; 32 int q[N]; 33 34 LL up(int i) { 35 return g[i] - sqr(sum[i]); 36 } 37 38 LL up(int i, int j) { 39 return up(j) - up(i); 40 } 41 42 LL down(int i, int j) { // >= 0 43 return sum[j] - sum[i]; 44 } 45 46 double slope(int i, int j) { 47 return up(i, j) / (double) down(i, j); 48 } 49 int n; 50 51 struct Node { 52 LL x, y; 53 Node() {} 54 Node(const LL& x, const LL& y) : x(x), y(y) {} 55 Node operator - (const Node& rhs) const { 56 return Node(x - rhs.x, y - rhs.y); 57 } 58 }p[N]; 59 60 LL Cross(const Node& a, const Node& b) { 61 return a.x * b.y - b.x * a.y; 62 } 63 64 void dp(int st) { 65 int L = 0, R = 0; 66 q[R++] = st; 67 for(int i = st + 1; i <= n; i++) { 68 // while(L + 1 < R && -sum[i] < slope(q[L], q[L + 1])) L++; 69 // while(L + 1 < R && -sum[i] * down(q[L], q[L + 1]) < up(q[L], q[L + 1])) L++; 70 while(L + 1 < R && Cross(Node(1, -sum[i]), p[L + 1] - p[L]) >= 0) L++; 71 int j = q[L]; 72 f[i] = g[j] + sum[j] * (sum[i] - sum[j]); 73 // while(L + 1 < R && slope(q[R - 2], q[R - 1]) < slope(q[R - 2], i)) R--; 74 // while(L + 1 < R && up(q[R - 2], q[R - 1]) * down(q[R - 2], i) < up(q[R - 2], i) * down(q[R - 2], q[R - 1])) R--; 75 Node u(sum[i], up(i)); 76 while(L + 1 < R && Cross(p[R - 1] - p[R - 2], u - p[R - 2]) >= 0) R--; 77 q[R] = i, p[R++] = u; 78 } 79 for(int i = st + 1; i <= n; i++) g[i] = f[i]; 80 } 81 82 int main() { 83 #ifdef DEBUG 84 freopen("in.txt", "r", stdin); 85 freopen("out.txt", "w", stdout); 86 #endif 87 88 read(n); 89 int k = read<int>(); 90 91 for(int i = 1; i <= n; i++) { 92 int x = read<int>(); 93 if(!x) i--, n--; 94 else sum[i] = sum[i-1] + x; 95 // sum[i] = sum[i-1] + read<int>(); 96 } 97 98 for(int i = 1; i <= k; i++) dp(i); 99 100 printf("%lld\n", g[n]); 101 102 return 0; 103 }
原文出处http://www.cnblogs.com/showson/