划分树,统计每层移到左边的数的和.

Minimum Sum

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 2959    Accepted Submission(s): 684

Problem Description
You are given N positive integers, denoted as x0, x1 ... xN-1. Then give you some intervals [l, r]. For each interval, you need to find a number x to make as small as possible!
 
Input
The first line is an integer T (T <= 10), indicating the number of test cases. For each test case, an integer N (1 <= N <= 100,000) comes first. Then comes N positive integers x (1 <= x <= 1,000, 000,000) in the next line. Finally, comes an integer Q (1 <=
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
For the k-th test case, first output “Case #k:” in a separate line. Then output Q lines, each line is the minimum value of  . Output a blank line after every test case.
 
Sample Input
2 5
3 6 2 2 4
2
1 4
0 2 2
7 7
2
0 1
1 1
 
Sample Output
Case #1:
6
4 Case #2:
0
0
 
Author
standy
 
Source
 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn=100010; typedef long long int LL; int tree[18][maxn];
LL sumL[18][maxn];
int sorted[maxn];
int toleft[18][maxn]; void build(int l,int r,int dep)
{
if(l==r) return ;
int mid=(l+r)/2;
int same=mid-l+1;
for(int i=l;i<=r;i++)
if(tree[dep][i]<sorted[mid]) same--;
int lpos=l,rpos=mid+1;
for(int i=l;i<=r;i++)
{
if(tree[dep][i]<sorted[mid])
{
tree[dep+1][lpos++]=tree[dep][i];
sumL[dep][i]=sumL[dep][i-1]+tree[dep][i];
}
else if(tree[dep][i]==sorted[mid]&&same>0)
{
tree[dep+1][lpos++]=tree[dep][i];
sumL[dep][i]=sumL[dep][i-1]+tree[dep][i];
same--;
}
else
{
tree[dep+1][rpos++]=tree[dep][i];
sumL[dep][i]=sumL[dep][i-1];
}
toleft[dep][i]=toleft[dep][l-1]+lpos-l;
}
build(l,mid,dep+1); build(mid+1,r,dep+1);
} LL SUMOFLEFT,NUMOFLEFT; LL query(int L,int R,int l,int r,int dep,int k)
{
if(l==r) return tree[dep][l];
int mid=(L+R)/2;
int cnt=toleft[dep][r]-toleft[dep][l-1];
if(cnt>=k)
{
int newl=L+toleft[dep][l-1]-toleft[dep][L-1];
int newr=newl+cnt-1;
return query(L,mid,newl,newr,dep+1,k);
}
else
{
SUMOFLEFT+=sumL[dep][r]-sumL[dep][l-1];
NUMOFLEFT+=cnt; int newr=r+toleft[dep][R]-toleft[dep][r];
int newl=newr-(r-l-cnt);
return query(mid+1,R,newl,newr,dep+1,k-cnt);
}
} int n,m;
LL sum[maxn]; int main()
{
int T_T,cas=1;
scanf("%d",&T_T);
while(T_T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",sorted+i);
tree[0][i]=sorted[i];
sum[i]=sum[i-1]+sorted[i];
}
sort(sorted+1,sorted+1+n);
build(1,n,0);
scanf("%d",&m);
printf("Case #%d:\n",cas++);
while(m--)
{
int l,r,k;
scanf("%d%d",&l,&r);
l++; r++;
k=(l+r)/2-l+1;
SUMOFLEFT=0;NUMOFLEFT=0;
LL ave=query(1,n,l,r,0,k);
printf("%I64d\n",(sum[r]-sum[l-1]-SUMOFLEFT)-SUMOFLEFT+(NUMOFLEFT-(r-l+1-NUMOFLEFT))*ave);
}
putchar(10);
}
return 0;
}

最新文章

  1. PHP多维数组根据其中一个字段的值排序
  2. C#给其他程序发消息
  3. [poj2337]求字典序最小欧拉回路
  4. Linux下怎么删除非空目录
  5. nginx 的信号控制概述
  6. 学习rabbitmq
  7. 用CocoaPods做iOS程序的依赖管理
  8. (一)解决Sublime Text 2中文显示乱码问题
  9. Keepalived高可用软件的安装与配置
  10. core&mdash;线程与IO
  11. js中动态载入css js样式
  12. Android最新源码4.3下载-教程 2013-11
  13. 「mysql优化专题」90%程序员面试都用得上的索引优化手册(5)
  14. bzoj5153&amp;uoj348 【WC2018】州区划分
  15. lazy_import源码解析(原创)
  16. Software tips
  17. Python模块学习 - fnmatch &amp; glob
  18. 【转帖】流程与IT管理部——IT支撑业务变革的必然趋势
  19. RN与android原生开发混合后的环境报错问题
  20. [原][c++][数学]osg常用图形数学算法小结

热门文章

  1. Android之WebView的使用样例——WebSetting、WebViewClient、WebChromeClient
  2. 质量平台建设之Mock平台
  3. 【HTML 元素】嵌入另一张HTML文档、通过插件嵌入内容、嵌入数字表现形式
  4. 排查 “Detected Tx Unit Hang”问题
  5. Android学习(十九)Dialog对话框
  6. UltraISO 9.6.5.3237
  7. mybatis like写法
  8. HDU 3732 Ahui Writes Word(多重背包)
  9. Pycharm中的scrapy安装教程
  10. linux 登陆key生成