zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第50章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第49章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第48章 读书笔记(待更新)
    Spring Boot 中使用 Quartz 实现任务调度
    实战 FastDFS Java 客户端上传文件
    分布式文件系统之 FastDFS
    Java 持久层框架之 MyBatis
    C语言实现贪吃蛇
    [转载]分享三篇非常好的学习心得
    selenium加载cookie报错问题:selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cookie domain
  • 原文地址:https://www.cnblogs.com/jklongint/p/4369494.html
Copyright © 2011-2022 走看看