题目传送门//res tp hdu

目的

对长度为n的区间,给定q个子区间,求一x,使得区间内所有元素与x的差的绝对值之和最小。

多测。

n 1e5

q 1e5

ai [1,1e9] (i∈[1,n]);

数据结构

划分树

tip

该划分树维护的cnt并非元素所在区间内,该元素之前进入左子树的元素个数,而是整个区间内,该元素之前进入左子树的元素个数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int L = 100000+50;
typedef long long ll;
int n,q;
int tree[18][L];
int cnt[18][L];
ll sum[18][L],ans;
int a[L],sorted[L]; void build(int de,int l,int r){
if(l == r){
sum[de][l] = sum[de][l-1] + tree[de][l];return;
}
if(de == 0){
for(int i = 1;i<=r;++i)
tree[de][i] = a[i];
}
int mi=(l+r)>>1;
int scnt = mi - l + 1;
ll M = sorted[mi];
for(int i = l;i<=mi;++i) if(sorted[i] < M)
scnt--;
int pl = l,pr = mi + 1;
for(int i = l;i<=r;++i){
ll num =tree[de][i];
if(num == M){
if(scnt){
scnt--;
tree[de+1][pl++] = num;
cnt[de][i]++;
}
else
tree[de+1][pr++] = num;
}
else if(num < M){
tree[de+1][pl++] = num;
cnt[de][i]++;
}
else
tree[de+1][pr++] = num;
sum[de][i] = sum[de][i-1] + tree[de][i];
cnt[de][i] += cnt[de][i-1];
}
build(de+1,l,mi);
build(de+1,mi+1,r);
} ll query(int de,int L,int R,int l,int r,int k){
if(L == R) return tree[de][L]; int mi = (L + R)>>1;
int lo1,lo2,hi1,hi2;
int CNT = cnt[de][r] - cnt[de][l-1];
lo1 = L + cnt[de][l-1] - cnt[de][L-1];
hi1 = L + cnt[de][r] - cnt[de][L-1] - 1;
lo2 = mi + 1 + l - L - cnt[de][l-1] + cnt[de][L-1];
hi2 = mi + 1 + r - L - cnt[de][r] + cnt[de][L-1];
if(k <= CNT){
if(hi2 >= lo2)
ans += sum[de+1][hi2] - sum[de+1][lo2-1];
return query(de+1,L,mi,lo1,hi1,k);
}
else{
if(hi1>=lo1)
ans -= sum[de+1][hi1] - sum[de+1][lo1-1];
return query(de+1,mi+1,R,lo2,hi2, k - CNT);
}
} int main(){
int T,l,r;
int icase = 1;
scanf(" %d",&T);
while(T--){
scanf(" %d",&n);
memset(sum,0,sizeof(sum));
memset(cnt,0,sizeof(cnt));
for(int i = 1;i<=n;++i){
scanf(" %d",a + i);
sorted[i] = a[i];
}
sort(sorted+1,sorted+1+n);
build(0,1,n);
scanf(" %d",&q);
printf("Case #%d:\n",icase++);
while(q--){
ans = 0;
scanf(" %d %d",&l,&r);
l++;r++;
ll t = query(0,1,n,l,r,(r - l)/2 + 1);
if((r-l)%2 == 1)
ans -= t;
printf("%lld\n", ans);
}
cout<<endl;
}
}

hdu 3473 区间条件极值 - 区间 差的绝对值 之和的最小的更多相关文章

  1. hdu 6601 区间条件极值 - 区间 最大 三角形周长

    题目传送门//res tp hdu 目的 对长度为n的区间,给定q个子区间,求其元素能构成三角形的最大周长.有多组测试. n 1e5 q 1e5 ai [1,1e9] (i∈[1,n]); 数据结构 ...

  2. 563. Binary Tree Tilt 子节点差的绝对值之和

    [抄题]: Given a binary tree, return the tilt of the whole tree. The tilt of a tree node is defined as ...

  3. hdu 5919 主席树(区间不同数的个数 + 区间第k大)

    Sequence II Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  4. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

  5. HDU 3397 Sequence operation(区间合并 + 区间更新)

    题目链接:pid=3397">http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给定n个数,由0,1构成.共同拥有5种操作. 每一个操 ...

  6. BZOJ 4127: Abs (树链剖分 线段树求区间绝对值之和 带区间加法)

    题意 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d(d>=0) 2 u v 表示询问路径 (u,v) 上点权绝对值的和 分析 绝对值之和不好处理,那么我们开 ...

  7. hdu 1698 线段树 区间更新 区间求和

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. hdu 3473 划分树

    Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

  9. pandas处理时间序列(2):DatetimeIndex、索引和选择、含有重复索引的时间序列、日期范围与频率和移位、时间区间和区间算术

    一.时间序列基础 1. 时间戳索引DatetimeIndex 生成20个DatetimeIndex from datetime import datetime dates = pd.date_rang ...

随机推荐

  1. dup2函数

    将当前系统中的进程信息打印到文件中 命令行:ps aux > out 将ps得到的信息重定向到out文件中 使用dup2文件在程序中完成. int dup2(int oldfd,int newf ...

  2. 简易的学生成绩管理系统(C++实现)

    最近浅显的学习了C++的基础知识,想来练练手,于是就用单链表写了最经典的小项目,存粹学习,所以就在控制台下写了,写的有点简陋,码了大概400多行. 下面上代码: #include <cstdli ...

  3. Linux环境下Gitblit服务搭建及秘钥配置

    一.安装gitblit服务 1.下载地址 https://pan.baidu.com/s/1wQ3TEE_gw5xZvyFPZB9xFg 2.上传至linux服务器并解压缩 tar xvf gitbl ...

  4. nginx实现动静分离的负载均衡集群

    实战: 一.源码编译安装nginx [root@tiandong63 ~]#yum groupinstall "Development Tools" "Developme ...

  5. Java编程思想代码环境配置

    官方代码网站已更改 https://github.com/BruceEckel/TIJ4-code 如果导入到IntelliJ中 方法1 在IntelliJ中新建一个Java项目将TIJ4-code- ...

  6. java什么时候进行垃圾回收,垃圾回收的执行流程

    java的垃圾回收分为 三个区域新生代 老年代 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间如果有 不进行垃圾回收 ,对象直接在伊甸园存储.如果伊甸园内存已满,会进行一次minor gc然后 ...

  7. Linux设备驱动程序 之 重要数据结构

    文件对象 文件对象是进程已经打开文件描述符的内存中的表示,单个文件可能有多个表示打开文件描述符的file结构: struct file { union { struct llist_node fu_l ...

  8. SDN上机第4次作业

    1. 解压安装OpenDayLight控制器(本次实验统一使用Beryllium版本) 1)JDK的安装与环境配置 ​ 嗯,装这个东西还得先装JDK: ​ 在线真人手把手教你安装jdk ​ 输入sud ...

  9. 之前有面试到两个日期的大小比较方式,现在整理一下几种方法。   例子:   String beginTime=new String("2017-06-09 10:22:22");     String endTime=new String("2017-05-08 11:22:22");  1  直接用Date自带方法before()和after()比较 SimpleDateFormat d

    各种数据类型(日期/时间.integer.floating point和numeric)转换成格式化的字符串以及反过来从格式化的字符串转换成指定的数据类型.下面列出了这些函数,它们都遵循一个公共的调用 ...

  10. HearthBuddy遇奥秘解决方法

    https://tieba.baidu.com/g/5808796816 链接: https://pan.baidu.com/s/1NPQTOfxbN_4alP7J-XWuVw 密码: xfj1