窝只是来留坑的qwq
为毛别人家的乘积式可以过?
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 = 50000 + 10; 26 27 LL f[N], k[N], c; 28 29 LL sqr(const LL& x) { 30 return x * x; 31 } 32 33 LL up(int i) { 34 return k[i] * (k[i] + c * 2) + f[i]; 35 } 36 37 LL up(int i, int j) { 38 return up(j) - up(i); 39 } 40 41 LL down(int i, int j) { 42 return 2 * (k[j] - k[i]); 43 } 44 45 double slope(int i, int j) { 46 return up(i, j) / down(i, j); 47 } 48 49 int q[N]; 50 51 int main() { 52 #ifdef DEBUG 53 freopen("in.txt", "r", stdin); 54 freopen("out.txt", "w", stdout); 55 #endif 56 57 int n; 58 read(n), read(c), ++c; 59 for(int i = 1; i <= n; i++) k[i] = k[i-1] + read<int>(); 60 for(int i = 1; i <= n; i++) k[i] += i; 61 62 int L = 0, R = 0; 63 q[R++] = 0; 64 for(int i = 1; i <= n; i++) { 65 while(L + 1 < R && k[i] > slope(q[L], q[L + 1])) L++; 66 // while(L + 1 < R && k[i] * down(q[L], q[L + 1]) > up(q[L], q[L + 1])) L++; 67 int j = q[L]; 68 f[i] = f[j] + sqr(k[i] - k[j] - c); 69 while(L + 1 < R && slope(q[R - 2], q[R - 1]) > slope(q[R - 2], i)) R--; 70 // 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--; 71 q[R++] = i; 72 } 73 74 printf("%lld ", f[n]); 75 76 return 0; 77 }
updated2016.3.23
把向量判断的又写了一遍
就过了
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;
template<typename Q> Q &read(Q &x) {
static char c, f;
for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
if(f) x = -x; return x;
}
template<typename Q> Q read() {
static Q x; read(x); return x;
}
typedef long long LL;
const int N = 50000 + 10;
struct Point {
LL x, y;
Point() {}
Point(LL x, LL y) : x(x), y(y) {}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
LL f(LL k) const {
return x * k + y;
}
};
LL Cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
}
Point p[N];
LL k[N], f[N];
LL sqr(const LL &x) {
return x * x;
}
int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n, c;
read(n), ++read(c);
for(int i = 1; i <= n; i++) {
read(k[i]) += k[i-1] + 1;
}
int L = 0, R = 0;
p[R++] = Point(0, 0);
for(int i = 1; i <= n; i++) {
while(L + 1 < R && p[L].f(k[i]) > p[L + 1].f(k[i])) L++;
f[i] = p[L].f(k[i]) + sqr(k[i] - c);
Point np(-2 * k[i], f[i] + k[i] * (k[i] + 2 * c));
while(L + 1 < R && Cross(np - p[R - 2], np - p[R - 1]) >= 0) R--;
p[R++] = np;
}
printf("%lld
", f[n]);
return 0;
}