hdu 3473 Minimum Sum(划分树)
375MS 30512K
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
#define MAXN 100005
#define MAXLOG 20
int sorted[MAXN],seq[MAXLOG][MAXN],toleft[MAXLOG][MAXN];
LL total[MAXN],sum_toleft[MAXLOG][MAXN];
struct STNode
{
int l,r;
};
STNode node[MAXN*3];
void build(int l,int r,int idx,int d)
{
node[idx].l = l;
node[idx].r = r;
if(l == r) return;
int mid = (l+r)/2,lsame,i;
lsame = mid - l + 1;
for(i=l; i<=r; i++)
if(seq[d][i] < sorted[mid]) lsame--;
int lpos=l,rpos=mid+1;
for(i=l; i<=r; i++)
{
if(i == l)
{
toleft[d][i] = 0;
sum_toleft[d][i] = 0;
}
else
{
toleft[d][i] = toleft[d][i-1];
sum_toleft[d][i] = sum_toleft[d][i-1];
}
if(seq[d][i] < sorted[mid])
{
toleft[d][i]++;
seq[d+1][lpos++] = seq[d][i];
sum_toleft[d][i] += seq[d][i];
}
else if(seq[d][i] > sorted[mid]) seq[d+1][rpos++] = seq[d][i];
else
{
if(lsame > 0)
{
lsame--;
toleft[d][i]++;
seq[d+1][lpos++] = seq[d][i];
sum_toleft[d][i] += seq[d][i];
}
else seq[d+1][rpos++] = seq[d][i];
}
}
build(l,mid,idx*2,d+1);
build(mid+1,r,idx*2+1,d+1);
}
LL num_lessMid,sum_lessMid;//设查询区间为[i,j],该区间中位数为m,则它们分别为小于等于m的个数及和
int query(int l,int r,int k,int idx,int d)
{
if(l == r) return seq[d][l];
int ss,s;
LL lsumTmp; //[l,r]小于中位数的和,只是临时的,真正记录的是sum_lessMid
if( l == node[idx].l)
{
ss = 0;
s = toleft[d][r];
lsumTmp = sum_toleft[d][r];
}
else
{
ss = toleft[d][l-1];
s = toleft[d][r] - ss;
lsumTmp = sum_toleft[d][r] - sum_toleft[d][l-1];
}
int newl,newr;
if(s >= k)
{
newl = node[idx].l + ss;
newr = newl + s - 1;
return query(newl,newr,k,idx*2,d+1);
}
else
{
int bb,b;
bb = l - node[idx].l - ss;
b = r - l + 1 - s;
newl = node[idx*2+1].l + bb;
newr = newl + b - 1;
num_lessMid += s;
sum_lessMid += lsumTmp;
return query(newl,newr,k-s,idx*2+1,d+1);
}
}
LL ask(int l,int r)
{
num_lessMid = sum_lessMid = 0;
LL median = query(l,r,(r-l)/2+1,1,1);
LL ans = median * num_lessMid - sum_lessMid;
LL sum_greaterMid = total[r] - total[l-1] - sum_lessMid;
ans += sum_greaterMid - median * ( r - l + 1 -num_lessMid );
return ans;
}
int main()
{
int T,cas,n,q,i,j;
scanf("%d",&T);
for(cas=1; cas<=T; cas++)
{
total[0]=0;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&sorted[i]);
seq[1][i]=sorted[i];
total[i]=total[i-1]+sorted[i];
}
sort(sorted+1,sorted+n+1);
build(1,n,1,1);
scanf("%d",&q);
printf("Case #%d:\n",cas);
while(q--)
{
scanf("%d %d",&i,&j);
printf("%I64d\n",ask(i+1,j+1));
}
printf("\n");
}
return 0;
}
浙公网安备 33010602011771号