Minimum Sum

被这个题坑了一下午,原来只需找一个最中间的数即可,我以为是平均数。

题意:找一个数使得这个数和区间内所有数的差的绝对值最小。输出最小值。

开始用线段树来了一发果断T了,然后各种优化依然T不断。于是只能用划分树做。不过,其实熟悉划分树也是模板水题。

打一个前缀和,然后这个数肯定是这个区间从大到小排在最中间的。所以查询一遍将小于中间这个数的和加起来,然后得到将小于这个数的个数。分为前半段和后半段分别加起来即可。

手残将一个地方写错了,然后无限RE。。。。最后一行一行debug,心塞。

ll sum[N],lsum[20][N];
int tree[20][N],a[N],t_l[20][N];
void build(int l,int r,int id)
{
if(l==r) return ;
int mid=(l+r)/2;
int same=mid-l+1;
for(int i=l;i<=r;i++) if(tree[id][i]<a[mid]) same--;
int lp=l,rp=mid+1;
for(int i=l;i<=r;i++)
{
if(tree[id][i]<a[mid])
{
tree[id+1][lp++]=tree[id][i];
lsum[id][i]=lsum[id][i-1]+tree[id][i];
}
else if(tree[id][i]==a[mid]&&same>0)
{
tree[id+1][lp++]=tree[id][i],same--;
lsum[id][i]=lsum[id][i-1]+tree[id][i];
}
else
{
tree[id+1][rp++]=tree[id][i];
lsum[id][i]=lsum[id][i-1];
}
t_l[id][i]=t_l[id][l-1]+lp-l;
}
build(l,mid,id+1);
build(mid+1,r,id+1);
}
ll isum;
int num;
int find(int l,int r,int k,int L,int R,int id)
{
if(l==r) return tree[id][l];
int mid=(L+R)/2;
int cnt=t_l[id][r]-t_l[id][l-1];
if(cnt>=k)
{
int newl=L+t_l[id][l-1]-t_l[id][L-1];
int newr=newl+cnt-1;
return find(newl,newr,k,L,mid,id+1);
}
else
{
num+=cnt;
isum+=lsum[id][r]-lsum[id][l-1];
int newr=r+t_l[id][R]-t_l[id][r];
int newl=newr-(r-l-cnt);
return find(newl,newr,k-cnt,mid+1,R,id+1);
}
}
int main()
{
int t,n,m;
scanf("%d",&t);
int t1=t;
while(t--)
{
scanf("%d",&n);
memset(sum,0,sizeof(sum));
for(int i=0; i<20; i++) tree[i][0]=t_l[i][0]=lsum[i][0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&tree[0][i]);
a[i]=tree[0][i];
sum[i]=sum[i-1]+a[i];
}
sort(a+1,a+n+1);
build(1,n,0);
scanf("%d",&m);
printf("Case #%d:\n",t1-t);
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
if(l==r) puts("0");
else
{
l++,r++;
int k=(r-l)/2+1;
num=0;//得到小于中间这个数的个数
isum=0;//得到小于中间这个数的和
ll x=find(l,r,k,1,n,0);
printf("%I64d\n",(ll)x*(num-(r-l+1-num))+sum[r]-sum[l-1]-isum-isum);
}
}
puts("");
}
return 0;
}

注意 long long 。

HDU-3743 Minimum Sum,划分树模板的更多相关文章

  1. HDU 3473 Minimum Sum 划分树,数据结构 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=3473 划分树模板题目,需要注意的是划分树的k是由1开始的 划分树: 参考:http://blog.csdn.ne ...

  2. HDU 3473 Minimum Sum 划分树

    题意: 给出一个长度为\(n(1 \leq n \leq 10^5)\)的序列\(a\) 有若干次查询l r:找到一个\(x\)使得\(\sum \limits_{l \leq i \leq r} \ ...

  3. hdu 2665 Kth number(划分树模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ]  改变一下输入就可以过 http://poj.org/problem? ...

  4. hdu 3473 Minimum Sum

    传送门 之前看挑战的时候看到一道分桶法的题目,其实我不是很明白分桶法应该怎么写.看到poj后面的讨论版上写着划分树裸题,而我以前就听说过了划分树,就干脆拿来学习一下.在写这篇博客的时候,其实我还是对这 ...

  5. HDU 2665 Kth number(划分树)

    Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  7. HDU 4417 Super Mario(划分树)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  9. HDU 3473 Minimum Sum (划分树)

    题意:给定一个数组,有Q次的询问,每次询问的格式为(l,r),表示求区间中一个数x,使得sum = sigma|x - xi|最小(i在[l,r]之间),输出最小的sum. 思路:本题一定是要O(nl ...

随机推荐

  1. VC运行时库(/MD、/MT等)

    VC项目属性→配置属性→C/C++→代码生成→运行时库 可以采用的方式有:多线程(/MT).多线程调试(/MTd).多线程DLL(/MD).多线程调试DLL(/MDd).单线程(/ML).单线程调试( ...

  2. Android用Intent来启动Service报“java.lang.IllegalArgumentException: Service Intent must be explicit”错误的解决方法

    今天没事来写个播放器,照搬书上的原句,其中一句 //用于启动和停止service的Intent final Intent it = new Intent("android.mu.action ...

  3. Android学习总结(六)———— 发送自定义广播

    一.两种广播类型 2.1 标准广播 是一种完全异步执行的广播,在广播发出去之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言.这种广播的效率会比较高,但同时也 ...

  4. iview 验证 trigger: 'blur,change', 同时加两个,省的每次还想input 还是 select

    iview 验证 trigger: 'blur,change', 同时加两个,省的每次还想input 还是 select dataRuleValidate: { name: [{ required: ...

  5. python3中bytes、hex和字符串相互转换

    1.字符串转bytes a = 'abcd' a1 = bytes(a,encoding('utf-8')) 2.bytes转字符串 a = b'abcd' a1 = bytes.decode(a , ...

  6. 【转】Java重构-策略模式、状态模式、卫语句

    前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...

  7. touch-action css属性 滚动和缩放手势

    CSS 属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动,缩放等) 默认情况下,平移(滚动) 和 缩放手势由浏览器专门处理.该属性用于 ...

  8. 欧拉函数φ(x)简要介绍及c++实现

    我还是很喜欢数论,从此吃喝不问,就此沉沦. 欧拉函数φ(x)的值为在[1,x)的区间内与x互质的数的个数 通式:    其中p1, p2……pn为x的所有质因数,x是不为0的整数.φ(1)=1. 注意 ...

  9. [LUOGU] 1717 钓鱼

    题目描述 话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,VIP999决定请他吃一次"年年大丰收",为了表示诚意,他还决定亲自去钓鱼,但是,因为 ...

  10. (48)zabbix报警媒介:自定义脚本Custom alertscripts

    自定义脚本媒介.zabbix会将信息传递给脚本,接下来你在脚本里面随意处理,一共会传递三个参数,按顺序接受也就是$1,$2,$3了,为了方便记忆,一般分别给他们赋值到To\Subject\body 配 ...