codeforces 631E Product Sum (dp凸单调性)
2016-03-06 10:45
351 查看
<a target=_blank href="http://codeforces.com/problemset/problem/631/E" style="color: rgb(0, 0, 204); margin-top: 0px; font-family: verdana, arial, sans-serif; font-size: 13px; text-align: center;">Product Sum</a>
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<stdio.h> #include<algorithm> #include<cmath> #include<map> #include<queue> #include<bitset> #include<stack> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") #define inf 0x3f3f3f3f #define eps 1e-9 #define pii pair<int,int> #define MP make_pair #define LL long long #define ULL unsigned long long #define N ( 1000000 + 10 ) #define M ( 200000 + 10) #define mod 1000000007 /* i < j $ans[i][j] = {(i, j-1) | a[i] * (i+1)} + a[j] * i - ( {(i,j-1) | a[i] * i} + a[j] * j); = a[j] * (i-j) + sum[i][j-1] = a[j] * i - a[j]*j + s[j-1] - s[i-1]; = a[j] * i - s[i-1] + s[j-1] - a[j]*j; // f[j] = s[j-1] - a[j] * j = a[j] * i - s[i-1] + f[j]; // g[i] i1 < i2 a[j] * i1 - s[i1-1] < a[j] * i2 - s[i2-1] (s[i2-1] - s[i1-1])/(i2-i1) > a[j] // ll(i1, i2) i1 < i2 < i ll(i1, i2) >= ll(i2, i) (s[i2-1] - s[i1-1])/(i2-i1) >= (s[i-1] - s[i2-1]) / (i-i2) -- #ans[i][j] = {(i+1, j) | a[i] * (i-1)} + a[i] * j - ( {(i+1,j) | a[i] * i} + a[i] * i); = a[i] * (j-i) - sum[i+1][j] = a[i] * j - a[i] * i - (s[j] - s[i]) = a[i] * j - s[j] + (-a[i] * i + s[i]) //-f[i] = a[i] * i - s[i] = a[i] * j - s[j] - f[i]; // g[j] j1 < j2 g[j1] > g[j2] a[i] * j1 - s[j1] - f[i] > a[i] * j2 - s[j2] - f[i] a[i] * j1 - s[j1] > a[i] * j2 - s[j2] a[i] * (j1-j2) > s[j1] - s[j2] (s[j1] - s[j2])/(j1-j2) < a[i] //ll(j2, j1) j < j1 < j2 ll(j1, j) >= (j2, j1) (s[j] - s[j1])/(j-j) >= (s[j1] - s[j2])/(j1-j2) > > ans = max(max(#ans[i]) + init) */ int a ; LL sum ; int tot; struct point{ LL a, s; LL get(int i) { return a * i - s; } }; point que ; bool judge(point i1, point i2, point i) { return (i.s - i2.s) * (i2.a - i1.a) <= (i2.s - i1.s) * (i.a - i2.a); } void insert(LL a, LL s) { point tmp; tmp.a = a, tmp.s = s; while(tot >= 2 && judge(que[tot-2], que[tot-1], tmp)) --tot; que[tot++] = tmp; } LL query(int x) { int l = -1, r = tot-1; while(r-l>1) { int mid = l+r>>1; if(que[mid].get(x) <= que[mid+1].get(x)) l = mid; else r = mid; } return que[r].get(x); } int main() { int n; scanf("%d", &n); LL ans = 0, init= 0; sum[0] = 0; for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); init += (LL)a[i] * i; sum[i] = sum[i-1] + a[i]; } tot = 0; for(int i = 2; i <= n; ++i) { insert(i-1, sum[i-2]); ans = max(ans, query(a[i]) + sum[i-1] - (LL)a[i] * i); } tot = 0; for(int i = n-1; i >= 1; --i) { insert(-(i+1), sum[i+1]); ans = max(ans, query(-a[i]) - (LL)a[i] * i + sum[i]); } printf("%I64d\n", ans + init); }
相关文章推荐
- 郭霖博客处转载的超赞的Volley用法
- 算法导论——lec 11 动态规划及应用
- Spark 1.6.0 单机安装配置
- Log4J配置
- WEB中会话跟踪
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?
- 织梦建站:我们到底是改用GBK编码还是用UTF8编码?