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 ...
随机推荐
- 老板怎么办,我们网站遭到DDoS攻击又挂了?
相信现在正在阅读此文的你,一定听说过发生在上个月的史上最大的DDoS攻击. 美国东部时间2月28日,GitHub在一瞬间遭到高达1.35Tbps的带宽攻击.这次DDoS攻击几乎可以堪称是互联网有史以来 ...
- Scala Option类型
转载自: Scala 初学者指南, 这里有一系列很棒的文章 类型 Option 可能你已经见过它在 Map API 中的使用:在实现自己的提取器时,我们也用过它, 然而,它还需要更多的解释. 你可能会 ...
- nyoj 矩形个数
矩形的个数 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3 ...
- windows安装gcc编译器
由于vc6.0对c语言编译不是很好,有些语句是正确的,但是编译却不能通过 所以决定在windows中安装gcc编译器来使用! http://www.cnblogs.com/cryinstall/arc ...
- AngularJS1.X学习笔记8-自定义指令(上)
AngulaJS的指令是一种非常强大的特性,一个ng-repeat就能让我们非常方便的展示一个数据列表,指令相当于是一个组件,为我们将一些东西封装起来了,提供了复用的可能性.个人认为自定义指令还是比较 ...
- ( 转 ) WebApiTestClient 的使用
注意点:需要修改api路由规则,加上action: "api/{controller}/{action}/{id}" 1.如何引入组件 首先,我们需要定义一个API项目 然后通过N ...
- ELK学习总结(2-1)mavel -》sense 和 索引初始化
1.安装 sudo elasticsearch/bin/plugin -install elasticsearch/mavel/latest http://localhost:9200/_plugi ...
- Django小范围傻瓜总结
1.母版: layout.html {% block x %}{% endblock %} 2.子版: {% extends 'layout' %} {% block x %}.......{% en ...
- 一大波 Android 刘海屏来袭,全网最全适配技巧!
一.序 Hi,大家好,我是承香墨影! Apple 一直在引领设计的潮流,自从 iPhone X 发布之后,"刘海屏" 就一直存在争议.不过不管你怎样,Android 也要跻入 &q ...
- Java-NIO(八):DatagramChannel
Java NIO中的DatagramChannel是一个能收发UDP包的通道.操作步骤: 1)打开 DatagramChannel 2)接收/发送数据 同样它也支持NIO的非阻塞模式操作,例如: @T ...