枚举所有的区间。对于确定的区间,假设最终的高度为h,
代价是max(∑(Hi−h),∑(h−Hj))(Hi>h,Hj≤h)
等价于max(∑Hi−cnt(i)∗h,cnt(j)∗h−∑Hj)
(cnt(i)表示满足Hi>h的堆数, cnt(j)表示满足Hj≤h 的堆数)。∑Hi−cnt(i)∗h关于h呈递减,cnt(j)∗h−∑Hj关于h呈递增。一个递减到0,一个从0开始递增,所以代价与h的函数图像是V字形的,交点处代价最小。此时 ∑Hi−cnt(i)∗h=cnt(j)∗h−∑Hj,h=∑Hi+∑Hjcnt(i)+cnt(j),分母是总堆数W,分子是这个区间积木的总个数。h实际上就是这个区间的平均高度aver。考虑到四舍五入,答案是aver或者aver+1,当然还需要与题目给定的H做下比较,最终的方案是这3个数之一。确定高度之后,把高的变矮需要知道比当前高度大的个数以及高度总和,把矮的变高类似。因此添加一堆和删除一堆时,需要维护个数和总和。可以通过树状数组维护,整个问题的复杂度O((n+W)logn).
代码如下:
 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype> using namespace std; #define mem0(a) memset(a, 0, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define define_m int m = (l + r) >> 1
#define Rep(a, b) for(int a = 0; a < b; a++)
#define lowbit(x) ((x) & (-(x)))
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {} typedef double db;
typedef long long LL; const int dx[] = {, , -, };
const int dy[] = {, -, , };
const int maxn = 1e4 + ;
const int maxm = 1e5 + ;
const int MD = 1e9 +; struct Point {
int x, y;
bool operator < (const Point &opt) const {
return x < opt.x || x == opt.x && y < opt.y;
}
Point operator - (const Point &opt) const {
return Point(x - opt.x, y - opt.y);
}
constructInt2(Point, x, y);
void inp() {
scanf("%d %d", &x, &y);
}
void outp() {
printf("(%d, %d), ", x, y);
}
}; struct Trie {
const static int char_size = ;
int cc;
int cht[][char_size];
int mark[];
Trie() { cc = ; mem0(mark); mem0(cht); }
int Idex(char ch) { return ch - ''; }
void Insert(char s[], int v) {
int pos = ;
for(int i = ; s[i]; i++) {
int id = Idex(s[i]);
if(!cht[pos][id]) cht[pos][id] = ++cc;
pos = cht[pos][id];
}
mark[pos] = v;
}
bool Find(char s[]) {
int pos = ;
for(int i = ; s[i]; i++) {
int id = Idex(s[i]);
if(!cht[pos][id]) return ;
pos = cht[pos][id];
}
return mark[pos];
}
}; struct KMP {
int next[];
void GetNext(char s[]) {
mem0(next);
next[] = next[] = ;
for(int i = ; s[i]; i++) {
int j = next[i];
while(j && s[i] != s[j]) j = next[j];
next[i + ] = s[j] == s[i]? j + : ;
}
}
void Match(char s[], char t[]) {
int j = , len = strlen(t);
for(int i = ; s[i]; i++) {
while(j && s[i] != t[j]) j = next[j];
if(s[i] == t[j]) j++;
if(j == len) printf("%d\n", i - len + );
}
}
}; struct Matrix {
int a[][];
Matrix operator * (const Matrix &_A) const {
Matrix tmp;
mem0(tmp.a);
for(int i = ; i < ; i++) {
for(int j = ; j < ; j++) {
for(int k = ; k < ; k++) {
tmp.a[i][j] = ((LL)a[i][k] * _A.a[k][j] + tmp.a[i][j]) % MD;
}
}
}
return tmp;
}
}; struct Edge {
int u, v;
constructInt2(Edge, u, v);
}; struct Segment {
Point a, b;
void inp() {
scanf("%d%d%d%d", &a.x, &a.y, &b.x, &b.y);
if(a.x > b.x) {
swap(a.x, b.x);
swap(a.y, b.y);
}
}
}; Matrix CalcMatrix(Matrix a, int n) {
if(n == ) return a;
Matrix tmp = CalcMatrix(a, n >> );
tmp = tmp * tmp;
if(n & ) tmp = tmp * a;
return tmp;
} inline int ReadInt() {
char c = getchar();
while(!isdigit(c)) c = getchar(); int x = ;
while(isdigit(c)) {
x = x * + c - '';
c = getchar();
}
return x;
} inline void WriteInt(int i) {
int p = ;
static int buf[];
if(i == ) p++;
else while(i) {
buf[p++] = i % ;
i /= ;
}
for(int j = p - ; j; j--) putchar('' + buf[j]);
} int Cross(Point a, Point b) {
return a.x * b.y - a.y * b.x;
} int Dist2(Point a, Point b) {
int x = a.x - b.x, y = a.y - b.y;
return x * x + y * y;
}
int ConvexHull(Point *p, int n, Point *ch) {
sort(p, p + n);
int m = ;
for (int i = ; i < n; i++) {
while (m > && Cross(ch[m - ] - ch[m - ], p[i] - ch[m - ]) <= ) m--;
ch[m++] = p[i];
}
int k = m;
for (int i = n - ; i >= ; i--) {
while (m > k && Cross(ch[m - ] - ch[m - ], p[i] - ch[m - ]) <= ) m--;
ch[m++] = p[i];
}
if (n > ) m--;
return m;
} template<class edge> struct Graph {
vector<vector<edge> > adj;
Graph(int n) { adj.clear(); adj.resize(n + ); }
Graph() { adj.clear(); }
void resize(int n) { adj.resize(n + ); }
void add(int s, edge e){ adj[s].push_back(e); }
void del(int s, edge e) { adj[s].erase(find(iter(adj[s]), e)); }
void clear() { adj.clear(); }
vector<edge>& operator [](int t) { return adj[t]; }
}; template<class T> struct TreeArray {
vector<T> c;
int maxn;
TreeArray(int n) { c.resize(n + ); maxn = n; }
TreeArray() { c.clear(); maxn = ; }
void clear() { memset(&c[], , sizeof(T) * maxn); }
void resize(int n) { c.resize(n + ); maxn = n; }
void add(int p, T x) { while (p < maxn) { c[p] += x; p += lowbit(p); } }
T get(int p) { T res = ; while (p) { res += c[p]; p -= lowbit(p); } return res; }
T range(int a, int b) { return get(b) - get(a - ); }
}; int n, W, H, a[];
LL sum[], step, maxh;
TreeArray<LL> ta(), ta0();
void Check(int h, int r) {
if (sum[n + * W - ] < (LL)h * W) return ;
LL sum1 = ta0.get(h + ), sumall = sum[r] - sum[r - W], c = ta.get(h + );
LL newsum1 = h * c - sum1, newsum2 = sumall - h * W + newsum1;
LL res = max(newsum1, newsum2);
if (res < step || res == step && h > maxh) {
step = res;
maxh = h;
}
}
int main() {
//freopen("in.txt", "r", stdin);
while (cin >> n >> W >> H) {
mem0(a);
for (int i = ; i < n; i++) {
scanf("%d", a + i + W);
}
int total = n + * W;
for (int i = ; i < total; i++) sum[i] = sum[i - ] + a[i]; if (sum[total - ] < (LL)H * W) {
puts("-1");
continue;
} ta.clear();
ta0.clear();
step = H * W;
maxh = H;
ta.add(, W );
ta0.add(, ); for (int i = W; i < total; i++) {
int num = sum[i] - sum[i - W], ave = num / W;
if (ave < H) ave = H;
ta.add(a[i - W] + , -);
ta0.add(a[i - W] + , -a[i - W]);
ta.add(a[i] + , );
ta0.add(a[i] + , a[i]);
Check(ave, i);
Check(ave + , i);
}
cout << maxh << " " << step << endl;
}
return ;
}

[hdoj5192] 树状数组的更多相关文章

  1. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

  2. bzoj1878--离线+树状数组

    这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...

  3. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

  4. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  5. BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status] ...

  6. BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Di ...

  7. 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组

    E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

  8. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

  9. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

随机推荐

  1. 快速搭建网站信息库(小型Zoomeye)

    前言:本来是不想重复造车轮的,网上资料有开源的fofa,和一些设计.有的架设太复杂了,好用东西不会用,整个毛线.还有的没有完整代码. 设计方案:    测试平台:windows    测试环境:php ...

  2. P1464 Function

    Function 简   单   的   递   归 这道题一开始十分智障地用递归做,虽然知道没那么简单,但还是冒着送死的心态交了一遍,果然,如我所料 样例输入: 密密麻麻,几万行的样例输入 //:) ...

  3. 【山外笔记-SVN命令】svnlook命令详解

    本文打印版问文件下载地址 [山外笔记-SVN命令]svnlook命令详解-打印版.pdf 一.命令简介 svnlook是检验Subversion版本库不同方面的命令行工具,不会对版本库有任何修改,只是 ...

  4. Yii2.0 rules常用验证规则

    设置一个修改方法,但是save(),没有成功,数据修改失败,查了好久,一般情况就是不符合rules规则,而我没有设置rules规则,重新设置了一个不能为空,然后就修改成功,rules里面什么也不写,也 ...

  5. Springboot:thymeleaf模板(八)

    存放位置:resources\templates 访问方式:通过Controller请求访问,不可直接访问(相当于web项目的WEB-INF目录) 环境依赖: <!--thymeleaf模板支持 ...

  6. mysql参数max_binlog_cache_size设置不当引发的血案

    日常运维中的坑真是防不胜防,不一小心就遇到别人给你挖的坑.最近又遇到经验不足的DBA不知道从哪拷贝的配置文件(据说是当时参加某培训机构视频培训是资料里的模板,真的是误人子弟呀),其中把max_binl ...

  7. C#线程学习笔记

    本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/18/Thread.html,记录一下学习,方便后面资料查找 一.线程的介绍 进程(Proce ...

  8. 编程是要偷懒的--option简练写法

    没改前: if(!empty($search)){ $where['personal_name'] = array('like','%'. $search . '%'); $this -> as ...

  9. PHP中静态(static)调用非静态方法详解--调用!!!

    来源:https://www.cnblogs.com/yolo-bean/p/7739265.html 这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么 ...

  10. 《Metasploit魔鬼训练营》第一章实践作业

    <Metasploit魔鬼训练营>第一章实践作业 1.搜集Samba服务usermap_script安全漏洞的相关信息,画出该安全漏洞的生命周期图,标注各个重要事件点的日期,并提供详细描述 ...