• [hdoj5192] 树状数组


    枚举所有的区间。对于确定的区间,假设最终的高度为h,
    代价是max((Hih),(hHj))Hih,Hjh)
    等价于max(Hicnt(i)h,cnt(j)hHj)
    (cnt(i)表示满足Hih的堆数, cnt(j)表示满足Hjh 的堆数)。Hicnt(i)h关于h呈递减,cnt(j)hHj关于h呈递增。一个递减到0,一个从0开始递增,所以代价与h的函数图像是V字形的,交点处代价最小。此时 Hicnt(i)h=cnt(j)hHjh=Hi+Hjcnt(i)+cnt(j),分母是总堆数W,分子是这个区间积木的总个数。h实际上就是这个区间的平均高度aver。考虑到四舍五入,答案是aver或者aver+1,当然还需要与题目给定的H做下比较,最终的方案是这3个数之一。确定高度之后,把高的变矮需要知道比当前高度大的个数以及高度总和,把矮的变高类似。因此添加一堆和删除一堆时,需要维护个数和总和。可以通过树状数组维护,整个问题的复杂度O((n+W)logn).
    代码如下:
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <map>
      6 #include <queue>
      7 #include <cmath>
      8 #include <vector>
      9 #include <ctime>
     10 #include <cctype>
     11 
     12 using namespace std;
     13 
     14 #define mem0(a) memset(a, 0, sizeof(a))
     15 #define lson l, m, rt << 1
     16 #define rson m + 1, r, rt << 1 | 1
     17 #define define_m int m = (l + r) >> 1
     18 #define Rep(a, b) for(int a = 0; a < b; a++)
     19 #define lowbit(x) ((x) & (-(x)))
     20 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
     21 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
     22 
     23 typedef double db;
     24 typedef long long LL;
     25 
     26 const int dx[4] = {1, 0, -1, 0};
     27 const int dy[4] = {0, -1, 0, 1};
     28 const int maxn = 1e4 + 7;
     29 const int maxm = 1e5 + 7;
     30 const int MD = 1e9 +7;
     31 
     32 struct Point {
     33     int x, y;
     34     bool operator < (const Point &opt) const {
     35         return x < opt.x || x == opt.x && y < opt.y;
     36     }
     37     Point operator - (const Point &opt) const {
     38         return Point(x - opt.x, y - opt.y);
     39     }
     40     constructInt2(Point, x, y);
     41     void inp() {
     42         scanf("%d %d", &x, &y);
     43     }
     44     void outp() {
     45         printf("(%d, %d), ", x, y);
     46     }
     47 };
     48 
     49 struct Trie {
     50         const static int char_size = 26;
     51         int cc;
     52         int cht[100010][char_size];
     53         int mark[100010];
     54         Trie() { cc = 0; mem0(mark); mem0(cht); }
     55         int Idex(char ch) { return ch - '0'; }
     56         void Insert(char s[], int v) {
     57                 int pos = 0;
     58                 for(int i = 0; s[i]; i++) {
     59                         int id = Idex(s[i]);
     60                         if(!cht[pos][id]) cht[pos][id] = ++cc;
     61                         pos = cht[pos][id];
     62                 }
     63                 mark[pos] = v;
     64         }
     65         bool Find(char s[]) {
     66                 int pos = 0;
     67                 for(int i = 0; s[i]; i++) {
     68                         int id = Idex(s[i]);
     69                         if(!cht[pos][id]) return 0;
     70                         pos = cht[pos][id];
     71                 }
     72                 return mark[pos];
     73         }
     74 };
     75 
     76 struct KMP {
     77         int next[1000010];
     78         void GetNext(char s[]) {
     79                 mem0(next);
     80                 next[0] = next[1] = 0;
     81                 for(int i = 1; s[i]; i++) {
     82                         int j = next[i];
     83                         while(j && s[i] != s[j]) j = next[j];
     84                         next[i + 1] = s[j] == s[i]? j + 1 : 0;
     85                 }
     86         }
     87         void Match(char s[], char t[]) {
     88                 int j = 0, len = strlen(t);
     89                 for(int i = 0; s[i]; i++) {
     90                         while(j && s[i] != t[j]) j = next[j];
     91                         if(s[i] == t[j]) j++;
     92                         if(j == len) printf("%d
    ", i - len + 1);
     93                 }
     94         }
     95 };
     96 
     97 struct Matrix {
     98         int a[3][3];
     99         Matrix operator * (const Matrix &_A) const {
    100                 Matrix tmp;
    101                 mem0(tmp.a);
    102                 for(int i = 0; i < 3; i++) {
    103                         for(int j = 0; j < 3; j++) {
    104                                 for(int k = 0; k < 3; k++) {
    105                                         tmp.a[i][j] = ((LL)a[i][k] * _A.a[k][j] + tmp.a[i][j]) % MD;
    106                                 }
    107                         }
    108                 }
    109                 return tmp;
    110         }
    111 };
    112 
    113 struct Edge {
    114     int u, v;
    115     constructInt2(Edge, u, v);
    116 };
    117 
    118 struct Segment {
    119         Point a, b;
    120         void inp() {
    121                 scanf("%d%d%d%d", &a.x, &a.y, &b.x, &b.y);
    122                 if(a.x > b.x) {
    123                         swap(a.x, b.x);
    124                         swap(a.y, b.y);
    125                 }
    126         }
    127 };
    128 
    129 Matrix CalcMatrix(Matrix a, int n) {
    130         if(n == 1) return a;
    131         Matrix tmp = CalcMatrix(a, n >> 1);
    132         tmp = tmp * tmp;
    133         if(n & 1) tmp = tmp * a;
    134         return tmp;
    135 }
    136 
    137 inline int ReadInt() {
    138     char c = getchar();
    139     while(!isdigit(c)) c = getchar();
    140 
    141     int x = 0;
    142     while(isdigit(c)) {
    143         x = x * 10 + c - '0';
    144         c = getchar();
    145     }
    146     return x;
    147 }
    148 
    149 inline void WriteInt(int i) {
    150     int p = 0;
    151     static int buf[10];
    152     if(i == 0) p++;
    153     else while(i) {
    154         buf[p++] = i % 10;
    155         i /= 10;
    156     }
    157     for(int j = p - 1; j; j--) putchar('0' + buf[j]);
    158 }
    159 
    160 int Cross(Point a, Point b) {
    161     return a.x * b.y - a.y * b.x;
    162 }
    163 
    164 int Dist2(Point a, Point b) {
    165     int x = a.x - b.x, y = a.y - b.y;
    166     return x * x + y * y;
    167 }
    168 int ConvexHull(Point *p, int n, Point *ch) {
    169     sort(p, p + n);
    170     int m = 0;
    171     for (int i = 0; i < n; i++) {
    172         while (m > 1 && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m--;
    173         ch[m++] = p[i];
    174     }
    175     int k = m;
    176     for (int i = n - 2; i >= 0; i--) {
    177         while (m > k && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m--;
    178         ch[m++] = p[i];
    179     }
    180     if (n > 1) m--;
    181     return m;
    182 }
    183 
    184 template<class edge> struct Graph {
    185     vector<vector<edge> > adj;
    186     Graph(int n) { adj.clear(); adj.resize(n + 5); }
    187     Graph() { adj.clear(); }
    188     void resize(int n) { adj.resize(n + 5); }
    189     void add(int s, edge e){ adj[s].push_back(e); }
    190     void del(int s, edge e) { adj[s].erase(find(iter(adj[s]), e)); }
    191     void clear() { adj.clear(); }
    192     vector<edge>& operator [](int t) { return adj[t]; }
    193 };
    194 
    195 template<class T> struct TreeArray {
    196     vector<T> c;
    197     int maxn;
    198     TreeArray(int n) { c.resize(n + 5); maxn = n; }
    199     TreeArray() { c.clear(); maxn = 0; }
    200     void clear() { memset(&c[0], 0, sizeof(T) * maxn); }
    201     void resize(int n) { c.resize(n + 5); maxn = n; }
    202     void add(int p, T x) { while (p < maxn) { c[p] += x; p += lowbit(p); } }
    203     T get(int p) { T res = 0; while (p) { res += c[p]; p -= lowbit(p); } return res; }
    204     T range(int a, int b) { return get(b) - get(a - 1); }
    205 };
    206 
    207 int n, W, H, a[160000];
    208 LL sum[160000], step, maxh;
    209 TreeArray<LL> ta(50001), ta0(50001);
    210 void Check(int h, int r) {
    211     if (sum[n + 2 * W - 1] < (LL)h * W) return ;
    212     LL sum1 = ta0.get(h + 1), sumall = sum[r] - sum[r - W], c = ta.get(h + 1);
    213     LL newsum1 = h * c - sum1, newsum2 = sumall - h * W + newsum1;
    214     LL res = max(newsum1, newsum2);
    215     if (res < step || res == step && h > maxh) {
    216         step = res;
    217         maxh = h;
    218     }
    219 }
    220 int main() {
    221     //freopen("in.txt", "r", stdin);
    222     while (cin >> n >> W >> H) {
    223         mem0(a);
    224         for (int i = 0; i < n; i++) {
    225             scanf("%d", a + i + W);
    226         }
    227         int total = n + 2 * W;
    228         for (int i = 1; i < total; i++) sum[i] = sum[i - 1] + a[i];
    229 
    230         if (sum[total - 1] < (LL)H * W) {
    231             puts("-1");
    232             continue;
    233         }
    234 
    235         ta.clear();
    236         ta0.clear();
    237         step = H * W;
    238         maxh = H;
    239         ta.add(1, W );
    240         ta0.add(1, 0);
    241 
    242         for (int i = W; i < total; i++) {
    243             int num = sum[i] - sum[i - W], ave = num / W;
    244             if (ave < H) ave = H;
    245             ta.add(a[i - W] + 1, -1);
    246             ta0.add(a[i - W] + 1, -a[i - W]);
    247             ta.add(a[i] + 1, 1);
    248             ta0.add(a[i] + 1, a[i]);
    249             Check(ave, i);
    250             Check(ave + 1, i);
    251         }
    252         cout << maxh << " " << step << endl;
    253     }
    254     return 0;
    255 }
    View Code
  • 相关阅读:
    day38 20-Spring与Junit整合
    day38 19-Spring整合web开发
    day38 18-Spring的XML和注解的结合使用
    day38 17-Spring的Bean的属性注入:注解方式
    day38 16-Spring的Bean的装配:注解的方式
    day38 15-Spring的配置文件引入的问题
    day38 14-Spring的Bean的属性的注入:集合属性的注入
    day38 13-Spring的Bean的属性的注入:SpEL注入
    day38 12-Spring的Bean的属性的注入:名称空间p
    SqlServer与.NET的数据类型映射关系图
  • 原文地址:https://www.cnblogs.com/jklongint/p/4369494.html
Copyright © 2020-2023  润新知