[hdoj5192] 树状数组
- 枚举所有的区间。对于确定的区间,假设最终的高度为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] 树状数组的更多相关文章
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
- bzoj1878--离线+树状数组
这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...
- codeforces 597C C. Subsequences(dp+树状数组)
题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3289: Mato的文件管理[莫队算法 树状数组]
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2399 Solved: 988[Submit][Status][Di ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
随机推荐
- 参数化parameterized
pip install parameterized 注意:之前的nose-parameterized已经更新为parameterized库了 模块下测试方法直接使用parameterized impo ...
- google无法播放mp4 chrome无法播放h264
写在前面 我在chrome上无法播放h264+Acc的mp4,在firefox.ie都可以播放,而且此mp4在vlc终可以正常播放. 视频链接:http://106.14.221.185:7001/p ...
- [PHP]$_SERVER参数详情
来源:PHP中$_SERVER的详细参数与说明 $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关.$_SERVER['argv'] #传递给该脚 ...
- react: typescript system params optimize
1.system-params-service import paramCache from "../common/param-cache" import RequestPromi ...
- pytorch实现手动线性回归
import torch import matplotlib.pyplot as plt learning_rate = 0.1 #准备数据 #y = 3x +0.8 x = torch.randn( ...
- python爬虫(1)requests库
在pycharm中安装requests库的一种方法 首先找到设置 搜索然后安装,蓝色代表已经安装 requests库中的get请求 与HTTP协议相对应,requests库也有七种请求方式. 获取ur ...
- 2019-2020-1 20199308《Linux内核原理与分析》第七周作业
<Linux内核分析> 第六章 进程的描述和进程的创建 6.1 进程的描述 操作系统内核实现操作系统的三大管理功能: 进程管理(进程)-核心 内存管理(虚拟内存) 文件系统(文件) 为了管 ...
- Gym 101194F Mr. Panda and Fantastic Beasts
#include<bits/stdc++.h> using namespace std; #define ms(arr,a) memset(arr,a,sizeof arr) #defin ...
- 被@ResponseBoby注释的方法在拦截器的posthandle方法中设置cookie失效的问题
文章标题可能有点绕口.先来解释下遇到的问题. 我写了一个拦截器,希望能够实现保存特定方法的请求参数到cookie中. public class SaveParamInterceptor extends ...
- 常用的CSS小技巧
实际开发过程中会遇到一些需要用CSS小技巧处理的布局问题,现在分享几个个人工作中遇到的小问题和解决方案. 1.inline元素间的空白间隙 这里要介绍一个神器font-size:0. 如果你写了个列表 ...