Problem Description
部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和。随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守任务的士兵由于疲惫等原因能力指数将下降1。现在士兵们排成一排,请你计算出每次进行防守的士兵的参考指数。
Input
输入包含多组数据。
输入第一行有两个整数N,M,Q(1<=N<=100000,1<=M<=1000,1<=Q<=100000),第二行N个整数表示每个士兵对应的能力指数Xi(1<=Xi<=1000)。
接下来Q行,每行一个整数X,表示在原始队列中以X为起始的M个士兵替换之前的士兵进行防守。(1<=X<=N-M+1)
对于30%的数据1<=M,N,Q<=1000。
Output
输出Q行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。
Sample Input
5 3 32 1 3 1 4123
Sample Output
635
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
struct node
{
int l, r, sum, count;
}s[400001];
int n, m, Sum, Count, flag;
int Max( int a, int b )
{
return a>b?a:b;
}
int Min( int a, int b )
{
return a>b?b:a;
}
void build( int l, int r, int k )
{
s[k].l=l;
s[k].r=r;
s[k].sum=0;
s[k].count=0;
if( l==r )
return ;
int mid=( s[k].l+s[k].r )/2;
build( l, mid, k*2 );
build( mid+1, r, k*2+1 );
}
void update( int l, int r, int x, int k )
{
s[k].sum+=( r-l+1 )*x;
if( s[k].l==l&&s[k].r==r )
{
s[k].count+=x;
return ;
}
int mid=( s[k].l+s[k].r )/2;
if( l<=mid )
update( l, Min( r,mid ), x, k*2 );
if( r>mid )
update( Max( l, mid+1 ), r, x, k*2+1 );
}
void search( int l, int r, int k )
{
if( s[k].l==l&&s[k].r==r )
{
Sum+=s[k].sum;
return ;
}
Sum+=s[k].count*( r-l+1 );
int mid=( s[k].l+s[k].r )/2;
if( l<=mid )
search( l, Min( r,mid ), k*2 );
if( r>mid )
search( Max( l,mid+1 ), r, k*2+1 );
}
int main()
{
int i, j, k, t;
int x, Q;
while( scanf( "%d%d%d",&n, &m, &Q )!=-1 )
{
build( 1, n, 1 );
for( i=1;i<=n;i++ )
{
scanf( "%d",&x );
update( i,i,x,1 );
}
for( i=1;i<=Q;i++ )
{
Sum=0;
scanf( "%d",&x );
search( x,x+m-1,1 );
update( x,x+m-1,-1,1 );
printf( "%d\n",Sum );
}
}
return 0;
}