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 。

最新文章

  1. Shell教程
  2. C#:获取设备电量相关信息
  3. Zero-Copy&amp;sendfile浅析
  4. UI中 frame 与 transform的用法与总结
  5. Linux:实现Hadoop集群Master无密码登录(SSH)各个子节点
  6. mysql慢查询分析工作pt-query-digest的使用
  7. CentOs7&amp;zookeeper
  8. 使用netty构建一个socks proxy
  9. iOS是最安全的?苹果iOS恶意软件数量增速首次超过Android
  10. 获取txt md5值上传文件完整性校验
  11. (1)Phonics自然拼读 英语动画 Fun with Phonics 国际主流英语教学法
  12. 8款压箱底的Mac屏幕截图和录音录像工具软件,请你务必低调使用
  13. 【Java面试】1、基础知识篇
  14. PropertyGrid 重难点总结 转
  15. [转]小心C# 5.0 中的await and async模式造成的死锁
  16. HBase启动后发现HMaster进程消失了
  17. nginx做TCP代理实现群集
  18. 线程模型、pthread 系列函数 和 简单多线程服务器端程序
  19. streamsets mongodb destinations 使用
  20. 【转载】CreateThread与_beginthreadex本质区别

热门文章

  1. MFC命令行及CCommandLineInfo类
  2. openssl 安装配置
  3. GreenDao3.2的使用
  4. {ubuntu}乱七八糟重命名为1 2 3.....png
  5. uvm_marcos——UVM宏定义
  6. SnowKiting 2017/1/24
  7. 使用memcached缓存 替代solr中的LRUCache缓存
  8. shell脚本,awk 匹配的做修改后打印,不匹配的打印。
  9. ASIHTTPRequest简单学习
  10. ios之UIActionSheet