# BZOJ1367 [Baltic2004]sequence

(1)新加入一个数至数列末端，先把它当成单独一段

(2)每次看最后一段的w[tot]和前一段的w[tot - 1]，若w[tot] < w[tot - 1]，则说明合并可以更优，合并这两段。

(3)最后计算ans

 1 /**************************************************************
2     Problem: 1367
3     User: rausen
4     Language: C++
5     Result: Accepted
6     Time:5284 ms
7     Memory:59400 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13
14 using namespace std;
15 const int N = 1500000;
16
17 struct heap{
18     int v, l, r, dep;
19 }h[N];
20 int l[N], r[N], cnt[N], num[N], root[N];
21 int z[N];
22 int n, tot, Cnt;
23
25     int x = 0, sgn = 1;
26     char ch = getchar();
27     while (ch < '0' || ch > '9'){
28         if (ch == '-') sgn = -1;
29         ch = getchar();
30     }
31     while (ch >= '0' && ch <= '9'){
32         x = x * 10 + ch - '0';
33         ch = getchar();
34     }
35     return sgn * x;
36 }
37
38 int new_heap(int x){
39     h[++Cnt].v = x;
40     h[Cnt].l = h[Cnt].r = h[Cnt].dep = 0;
41     return Cnt;
42 }
43
44 int Merge(int x, int y){
45     if (!x || !y) return x + y;
46     if (h[x].v < h[y].v)
47         swap(x, y);
48     h[x].r = Merge(h[x].r, y);
49     if (h[h[x].l].dep < h[h[x].r].dep)
50         swap(h[x].l, h[x].r);
51     h[x].dep = h[h[x].r].dep + 1;
52     return x;
53 }
54
55 int Top(int x){
56     return h[x].v;
57 }
58
59 int Pop(int x){
60     return Merge(h[x].l, h[x].r);
61 }
62
63 int main(){
65     for (int i = 1; i <= n; ++i)
66         z[i] = read() - i;
67
68     for (int i = 1; i <= n; ++i){
69         ++tot;
70         root[tot] = new_heap(z[i]);
71         cnt[tot] = 1, num[tot] = 1;
72         l[tot] = i, r[tot] = i;
73
74         while (tot > 1 && Top(root[tot]) < Top(root[tot - 1])){
75             --tot;
76             root[tot] = Merge(root[tot], root[tot + 1]);
77             num[tot] += num[tot + 1], cnt[tot] += cnt[tot + 1], r[tot] = r[tot + 1];
78             for(; cnt[tot] * 2 > num[tot] + 1; --cnt[tot])
79                 root[tot] = Pop(root[tot]);
80         }
81     }
82
83     long long ans = 0;
84     for (int i = 1; i <= tot; ++i)
85         for (int j = l[i], w = Top(root[i]); j <= r[i]; ++j)
86             ans += abs(z[j] - w);
87     printf("%lld\n", ans);
88     return 0;
89 }
View Code

（p.s. 真是写的矬死了。。。越优化又慢，都醉了）

By Xs酱~ 转载请说明 博客地址：http://www.cnblogs.com/rausen
posted on 2014-10-18 21:55  Xs酱~  阅读(1551)  评论(0编辑  收藏  举报