Problem 2171 防守阵地 II
Accept: 298 Submit: 1119
Time Limit: 3000 mSec Memory Limit : 32768 KB
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
题目链接:点击打开链接
线段树的模板题, 每次询问过后士兵能力指数减1.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
#include "stack"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
#include "string"
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 5;
#define root 1, n, 1
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
int n, m, q, L, R, sum[MAXN << 2], add[MAXN << 2];
void push_up(int rt)
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void push_down(int l, int r, int rt)
{
if(add[rt] ) {
int m = (l + r) >> 1;
add[rt << 1] += add[rt] ;
sum[rt << 1] -= add[rt] * (m - l + 1);
add[rt << 1 | 1] += add[rt];
sum[rt << 1 | 1] -= add[rt] * (r - m);
add[rt] = 0;
}
}
void build(int l, int r, int rt)
{
add[rt] = 0;
if(l == r) {
scanf("%d", &sum[rt]);
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt);
}
void update(int l, int r, int rt)
{
if(L <= l && r <= R) {
add[rt]++;
sum[rt] -= r - l + 1;
return;
}
push_down(l, r, rt);
int m = (l + r) >> 1;
if(L <= m) update(lson);
if(m < R) update(rson);
push_up(rt);
}
int query(int l, int r, int rt)
{
if(L <= l && r <= R) return sum[rt];
push_down(l, r, rt);
int m = (l + r) >> 1, ans = 0;
if(L <= m) ans += query(lson);
if(m < R) ans += query(rson);
return ans;
}
int main(int argc, char const *argv[])
{
while(scanf("%d%d%d", &n, &m, &q) != EOF) {
build(root);
while(q--) {
scanf("%d", &L);
R = L + m - 1;
printf("%d\n", query(root));
update(root);
}
}
return 0;
}