题意:给定一个序列 s1, s2,...sn,以及一个k,求一个连续的k个数,把s[i]...s[i+k-1]变成一个数s',使得sigma(|s[j]-s'|)(i<=j<=i+k-1)最小

 思路:最近无聊切起poi。。顿感智商不够。。

         这道题很容易想到把这些数变成中位数最优。。那么就可以用平衡树维护了。。

         当然,直接用set维护也就够了。。不过为了练练代码。。我还是写了下splay。。

code:

  1 /*
  2  * Author:  Yzcstc
  3  * Created Time:  2014/11/8 19:03:57
  4  * File Name: klo.cpp
  5  */
  6 #include<cstdio>
  7 #include<iostream>
  8 #include<cstring>
  9 #include<cstdlib>
 10 #include<cmath>
 11 #include<algorithm>
 12 #include<string>
 13 #include<map>
 14 #include<set>
 15 #include<vector>
 16 #include<queue>
 17 #include<stack>
 18 #include<ctime>
 19 #define repf(i, a, b) for (int i = (a); i <= (b); ++i)
 20 #define M0(x)  memset(x, 0, sizeof(x))
 21 #define Inf  0x7fffffff
 22 using namespace std;
 23 const int maxn = 120000;
 24 typedef long long ll;
 25 int n, k;
 26 int a[101010];
 27 #define L ch[x][0]
 28 #define R ch[x][1]
 29 #define KT ch[ch[root][0]][1]
 30 struct SplayTree{
 31       int sz[maxn], pre[maxn], ch[maxn][2], v[maxn];
 32       ll sum[maxn];
 33       int m, root;
 34       void push_up(const int& x){
 35            sz[x] = sz[L] + sz[R] + 1;
 36            sum[x] = sum[L] + sum[R] + v[x];
 37       }
 38       void init(){
 39            M0(sz), M0(pre), M0(ch), M0(ch), M0(v);
 40       }
 41       void push_down(const int& x){
 42       }
 43       void rotate(int &x, const int f){
 44             int y = pre[x], z = pre[y];
 45             push_down(y), push_down(x);
 46             ch[y][!f] = ch[x][f];
 47             pre[ch[x][f]] = y;
 48             pre[x] = pre[y];
 49             if (z) ch[z][ch[z][1] == y] = x;
 50             ch[x][f] = y;
 51             pre[y] = x;
 52             push_up(y);
 53       }
 54       void splay(int &x, const int g){
 55             push_down(x);
 56             while (pre[x] != g){
 57                 int y = pre[x], z = pre[y];
 58                 if (z == g) rotate(x, ch[y][0] == x);
 59                 else {
 60                      int f = (ch[z][0] == y);
 61                      ch[y][!f] ? rotate(y, f) : rotate(x, !f);
 62                      rotate(x, f);
 63                 }
 64             }
 65             push_up(x);
 66             if (!g) root = x;
 67       }
 68       void rto(int k,const int g, int& y){
 69             int x = root;
 70             while (sz[L] + 1 != k){
 71                   push_down(x);
 72                   if (sz[L] >= k) x = L;
 73                   else {
 74                        k -= sz[L] + 1;
 75                        x = R;
 76                   }
 77             }
 78             y = x;
 79             splay(x, g);
 80       }
 81       int search(int x, int val){
 82             int y = -1;
 83             while (x){
 84                  y = x;
 85                  if (val <= v[x]) y = x, x = L;
 86                  else y = x, x = R; 
 87             }
 88             return y;
 89       }
 90       void insert(int x, int val){
 91            int y = search(root, val);
 92            ch[y][val > v[y]] = x;
 93            pre[x] = y;
 94            while (y) push_up(y), y = pre[y];
 95            splay(x, 0); 
 96       }
 97       int findpre(int x){
 98            x = L;
 99            while (R) x = R;
100            return x;
101       }
102       void split(int x){
103            splay(x, 0);
104            int lt = findpre(x);
105            if (lt){
106                   splay(lt, x);
107                   root = lt, pre[root] = 0;
108                   ch[root][1] = R;
109                   if (R) pre[R] = root;
110            } else root = R, pre[R] = 0;
111            push_up(root);
112            L = R = 0;
113       }
114       ll query(const int& n, int &vv){
115             int k = (n+1) / 2, x;
116             if (!(n & 1)) ++k;
117             rto(k, 0, x);
118             ll res = (ll)v[x] * (k-1) - sum[ch[root][0]] + sum[ch[root][1]] - (ll)v[x] * (n-k);
119             vv = v[x];
120             return res; 
121       }
122 } S;
123 
124 void init(){
125      for (int i = 1; i <= n; ++i)
126             scanf("%d", &a[i]);
127 }
128 
129 void solve(){
130      if (k == 1){
131            puts("0");
132            for (int i = 1; i <= n; ++i)
133                printf("%d\n", a[i]);
134            return;      
135      }
136      S.root = 1, S.sz[1] = 1, S.sum[1] = S.v[1] = a[1];
137      for (int i = 2; i <= n; ++i)
138            S.sz[i] = 1, S.v[i] = S.sum[i] = a[i];
139      for (int i = 2; i <= k; ++i)
140            S.insert(i, a[i]);
141      int ans_pos = 1, ans_val = 0, val;
142      ll ans = S.query(k, ans_val), tmp;
143      for (int i = k + 1; i <= n; ++i){
144             S.split(i-k);
145             S.insert(i, a[i]);
146             tmp = S.query(k, val);
147             if (tmp < ans)
148                  ans = tmp, ans_val = val, ans_pos = i - k + 1;
149      }
150      cout << ans << endl;
151      for (int i = ans_pos; i <= ans_pos+k-1; ++i) a[i] = ans_val;
152      for (int i = 1; i <= n; ++i) printf("%d\n", a[i]);
153 }
154 
155 int main(){
156 //    freopen("a.in", "r", stdin);
157 //    freopen("a.out", "w", stdout);
158     while (scanf("%d%d", &n, &k) != EOF){
159           init();
160           solve();
161     }
162     return 0;
163 }
View Code

相关文章:

  • 2021-06-22
  • 2021-10-12
  • 2022-03-05
  • 2022-12-23
  • 2021-06-01
  • 2021-10-12
猜你喜欢
  • 2022-02-13
  • 2021-05-16
  • 2021-08-14
  • 2022-02-18
  • 2022-01-09
  • 2021-05-16
相关资源
相似解决方案