http://acm.fzu.edu.cn/contest/problem.php?cid=139&sortid=2
加强版本,可以指定士兵的任意顺序。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 2000005
int as[N],c[N],d[N],cs[N];
int lowbit(int k)
{
return (-k)&k;
}
int getsum(int c[],int k)
{
int sum=0;
while(k && k<N){
sum+=c[k];
k+=lowbit(k);
}
return sum;
}
int realGetSum(int c[], int k){
return getsum(c, 1) - getsum(c, k + 1);
}
void update(int c[],int k,int detal)
{
while(k>0){
c[k]+=detal;
k-=lowbit(k);
}
}
int max(int x,int y){return x>y?x:y;}
int main(void)
{
int n,m,a,b,ans,i;
while(scanf("%d%d",&n,&m)==2)
{
int Max = 0;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
for(i = 0; i < m; ++ i){
scanf("%d",&a);
update(c,a,a);
update(d,a,1);
as[i]=a;
cs[i]=a;
Max = max(Max,a);
}
sort(as,as+m);
for(i = ans = 0; i < m; ++ i){
ans += as[i] * (i + 1);
}
for(i;i<n;i++){
a = cs[i-m];
scanf("%d",&b);
cs[i]= b;
int idx = realGetSum(d,a-1) + 1;
ans -= idx * a;
update(c,a,-a);
update(d,a,-1);
int suma = realGetSum(c,a);
int sumb = realGetSum(c,b);
if(sumb==suma){
ans += idx * b;
}else if(sumb > suma){
ans -= sumb - realGetSum(c,a-1);
ans += (realGetSum(d,b) + 1) * b;
}else{
ans += suma - realGetSum(c,a-1);
ans += (realGetSum(d,b - 1) + 1) * b;
}
update(c,b,b);
update(d,b,1);
Max = max(Max,a);
}
printf("%d\n",ans);
}
return 0;
}