hdu 3473 划分树
Minimum Sum
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3611 Accepted Submission(s): 829
assmall as possible!
Q <= 100,000), indicting there are Q queries. Each query consists of two integers l, r (0 <= l <= r < N), meaning the interval you should deal with.
. Output a blank line after everytest case.
5
3 6 2 2 4
2
1 4
0 2
2
7 7
2
0 1
1 1
6
4
Case #2:
0
0
题意:
给你一个区间,让你找出其中一个值,让所有值与它相减的绝对值的和最小。
思路:
于是成了找出其中的中间值减去最小,最开始简单粗暴地超时。然后发现求绝对值有点麻烦,于是在建树和查找的过程中找出比中间值小的数的和,然后分类计算吧。
感觉最开始没有考虑好方案,太随意了。
/*
hdu 3473
最开始直接算TL,然后发现由于是计算绝对值,在建树的时候需要记录比你查找的值小的和,
然后分开计算即可
*/ #include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <Map>
using namespace std;
typedef long long ll;
typedef long double ld; using namespace std; const int maxn = 100010; int tree[20][maxn];
int sorted[maxn];
int toleft[20][maxn];
ll sum[maxn];
ll lsum[20][maxn];
ll tsum; void build(int l,int r,int dep) //模拟快排 并记录左树中比i小的个数
{
if(l == r)
return;
int mid = (l+r)>>1;
int same = mid-l+1;//可能有很多值与中间那个相等,但不一定被分到左边
for(int i = l;i <= r;i++)
{
if(tree[dep][i] < sorted[mid])
same--;
}
int lpos = l;
int rpos = mid+1;
for(int i = l;i <= r;i++)
{
if(tree[dep][i] < sorted[mid]){
tree[dep+1][lpos++] = tree[dep][i];
lsum[dep][i] = lsum[dep][i-1] + tree[dep][i];
}
else if(tree[dep][i] == sorted[mid] && same > 0)
{
tree[dep+1][lpos++] = tree[dep][i];
lsum[dep][i] = lsum[dep][i-1] + tree[dep][i];
same --;
}
else
{
tree[dep+1][rpos++] = tree[dep][i];
lsum[dep][i] = lsum[dep][i-1];
}
toleft[dep][i] = toleft[dep][l-1] + lpos -l; }
build(l,mid,dep+1);
build(mid+1,r,dep+1);
} int query(int L,int R,int l,int r,int dep,int k)
{
if(l == r)
return tree[dep][l];
int mid = (L+R)>>1; int cnt = toleft[dep][r]-toleft[dep][l-1]; //所查找区间放在左树中的个数
if(cnt >= k)
{ //得到l左边放到左子树的个数,加上L即是开始位置
int lpos = L+toleft[dep][l-1]-toleft[dep][L-1];
int rpos = lpos+cnt-1; return query(L,mid,lpos,rpos,dep+1,k);
}
else
{ //R-r可以得出后面空出了多少位置
int rpos = r+toleft[dep][R]-toleft[dep][r];
int lpos = rpos-(r-l-cnt);
tsum += lsum[dep][r] - lsum[dep][l-1];
return query(mid+1,R,lpos,rpos,dep+1,k-cnt);
}
} int main()
{
int n,m,T;
int cas = 1;
scanf("%d",&T);
while(T--)
{ scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%d",&sorted[i]);
sum[i] = sum[i-1]+sorted[i];
tree[0][i] = sorted[i];
}
sort(sorted+1,sorted+n+1);
build(1,n,0);
scanf("%d",&m);
int l,r;
printf("Case #%d:\n",cas++);
while(m--)
{
scanf("%d%d",&l,&r);
l++;r++;tsum = 0;
ll k =(r-l)/2+1;
ll ans = 0;
ll aver = query(1,n,l,r,0,k);
ans = sum[r]-sum[l-1]-aver*(r-l+1-k)-tsum-aver;
ans += (k-1)*aver-tsum;
printf("%I64d\n",ans);
}
puts("");
}
return 0;
}
hdu 3473 划分树的更多相关文章
- HDU 4417 (划分树+区间小于k统计)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目大意:给定一个区间,以及一个k值,求该区间内小于等于k值的数的个数.注意区间是从0开始的 ...
- hdu 4251 划分树
思路:裸的划分树 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath ...
- hdu 2665 划分树
思路:裸的划分树 #include<iostream> #include<algorithm> #include<cstring> #include<cstd ...
- hdu 4417 划分树
思路:二分枚举区间第k大.用划分树查找是否符合要求的高度. #include<iostream> #include<algorithm> #include<cstdio& ...
- HDU 4417 划分树写法
Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...
- HDU 4417 划分树+二分
题意:有n个数.m个询问(l,r,k),问在区间[l,r] 有多少个数小于等于k. 划分树--查找区间第k大的数.... 利用划分树的性质.二分查找在区间[l,r]小于等于k的个数. 假设在区间第 i ...
- hdu 2665 划分树模板题(可作为模板)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 3473 Minimum Sum 划分树,数据结构 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=3473 划分树模板题目,需要注意的是划分树的k是由1开始的 划分树: 参考:http://blog.csdn.ne ...
- HDU 3473 Minimum Sum (划分树)
题意:给定一个数组,有Q次的询问,每次询问的格式为(l,r),表示求区间中一个数x,使得sum = sigma|x - xi|最小(i在[l,r]之间),输出最小的sum. 思路:本题一定是要O(nl ...
随机推荐
- Twisted 介绍 及TCP广播系统实例
twisted 提供更多传输层 udp,tcp,tls及应用层HTTP,FTP等协议的支持,在开发方法上更提供了丰富的特性来支持异步编程 安装twisted 建议使用anaconda 安装,conda ...
- Python扩展模块——调用WindowsAPI(pywin32的简单使用)
这块使用的比较少,只用到了模拟键盘按键, 调用鼠标比较费事,是通过像素坐标实现的,如果没有特殊需求或万不得已不建议使用 import win32con import win32api win32api ...
- 在Vim按了ctrl+s后
在windows我们码代码的时候习惯ctrl+s保存: 但在vim中使用ctrl+s之后终端就没反应了... vim: ctrl+s终止屏幕输出,敲的东西都有效,就是看不见. ctrl+q恢复:
- Python内置函数(58)——input
英文文档: input([prompt]) If the prompt argument is present, it is written to standard output without a ...
- Python内置函数(2)——divmod
英文文档: divmod(a, b) Take two (non complex) numbers as arguments and return a pair of numbers consisti ...
- Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。
Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber ...
- 用C#(.NET Core) 实现简单工厂和工厂方法模式
本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是 ...
- apollo1.7.1初探(一)安装apollo、创建并启动broker
Apache Apollo是一个代理服务器,是在ActiveMQ基础上发展而来的,支持STOMP, AMQP, MQTT, Openwire, SSL, and WebSockets 等多种协议. A ...
- Angular 学习笔记 ( CDK - Layout )
简单说就是 js 的 media query. 1. BreakpointObserver const layoutChanges = this.breakpointObserver.observe ...
- SpringMvc(4-1)Spring MVC 中的 forward 和 redirect
Spring MVC 中,我们在返回逻辑视图时,框架会通过 viewResolver 来解析得到具体的 View,然后向浏览器渲染.通过配置,我们配置某个 ViewResolver 如下: <b ...