大连海事大学第一届编程马拉松挑战赛多校联赛DIV1 第一场的1007,由于是private的比赛而且题目没有放出来,所以就不放题目连接了
题目大意就是一个数列实现区间值修改,区间值清零和区间查询,显然是线段树实现...
之前写的带Lazy标记的线段树只支持区间修改没有区间赋值,区间赋值跟修改还不太一样,相当于又打了一个标记,这个标记就是说:这个区间的值被清成了多少。
由于这道题的所有区间赋值都是清成0,所以打上标记为-1相当于区间赋值为0的标记,查询的之后和普通懒标记一样,先把标记下方然后继续查询。如果不是赋值为0标记那边换成一个结构体存赋成多少也是一样的。唯一的问题就是两种标记之间下放、查询的逻辑不能出错...一开始就这边没搞清楚WA了好几次.....
题目大意就是一个数列实现区间值修改,区间值清零和区间查询,显然是线段树实现...
之前写的带Lazy标记的线段树只支持区间修改没有区间赋值,区间赋值跟修改还不太一样,相当于又打了一个标记,这个标记就是说:这个区间的值被清成了多少。
由于这道题的所有区间赋值都是清成0,所以打上标记为-1相当于区间赋值为0的标记,查询的之后和普通懒标记一样,先把标记下方然后继续查询。如果不是赋值为0标记那边换成一个结构体存赋成多少也是一样的。唯一的问题就是两种标记之间下放、查询的逻辑不能出错...一开始就这边没搞清楚WA了好几次.....
线段树还是不太熟,这种基础的东西还是要多练,争取能尽早搞出一个自己用的惯又优美的线段树模板。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 100000+10;
#define lson step << 1
#define rson (step << 1) | 1
#define INF 0x3f3f3f3f
struct Node {
int left,right;
ll sum,lazy;
}L[N << 2];
void pushUp(int step)
{
step >>= 1;
while(step){
L[step].sum = L[lson].sum + L[rson].sum;
step = (step >> 1);
}
}
void work(int step){
L[lson].lazy = -1;
L[rson].lazy = -1;
L[lson].sum = 0;
L[rson].sum = 0;
L[step].lazy = 0;
}
void pushDown(int step)
{
ll tmp = L[step].lazy;
if(L[lson].lazy == -1 && L[lson].left != L[lson].right){
work(lson);
}
if(L[rson].lazy == -1 && L[rson].left != L[rson].right){
work(rson);
}
L[lson].lazy += tmp;
L[rson].lazy += tmp;
L[lson].sum += (L[lson].right - L[lson].left + 1) * tmp;
L[rson].sum += (L[rson].right - L[rson].left + 1) * tmp;
L[step].lazy = 0;
}
void init(int step,int l,int r)
{
L[step].left = l;
L[step].right = r;
L[step].sum = 0;
L[step].lazy = 0;
if(l == r)
return;
int m = (l+r)>>1;
init(lson, l ,m);
init(rson, m+1, r);
}
ll querys(int step,int l,int r)
{
if(l > r)return 0;
if(L[step].lazy != 0){
if(L[step].lazy == -1){
L[lson].lazy = -1;
L[rson].lazy = -1;
L[lson].sum = 0;
L[rson].sum = 0;
L[step].lazy = 0;
}
else
pushDown(step);
}
if(L[step].left == l && L[step].right == r){
ll a = L[step].sum;
return a;
}
int m = (L[step].left + L[step].right) >> 1;
if( r < m ) {
return querys(lson, l, r);
}
if( l > m ) {
return querys(rson, l, r);
}
return querys(lson, l, m) + querys(rson, m+1, r);
}
void update(int step,int p,int w)
{
if(L[step].left == L[step].right){
L[step].sum = w;
pushUp(step);
return ;
}
int m = (L[step].left + L[step].right) >> 1;
if(p <= m)update(lson, p, w);
else update(rson, p, w);
}
void update(int step,int l,int r,ll w)
{
if(l > r)return ;
if(L[step].lazy != 0){
if(L[step].lazy == -1){
L[lson].lazy = -1;
L[rson].lazy = -1;
L[lson].sum = 0;
L[rson].sum = 0;
L[step].lazy = 0;
}
else{
pushDown(step);
}
}
if(L[step].left == l && L[step].right == r){
L[step].lazy += w;
L[step].sum += w * (r-l+1);
pushUp(step);
return;
}
int m = (L[step].left + L[step].right) >> 1;
if( r < m ) {
update(lson, l, r , w);
return;
}
if( l > m ){
update(rson, l, r , w);
return;
}
update(lson, l, m , w);
update(rson, m+1, r, w);
}
void update2(int step,int l,int r,int w)
{
if(l > r)return ;
if(L[step].lazy != 0){
if(L[step].lazy == -1)return;
pushDown(step);
}
if(L[step].left == l && L[step].right == r){
L[step].lazy = -1;
L[step].sum = 0;
pushUp(step);
return;
}
int m = (L[step].left + L[step].right) >> 1;
if( r <= m ) {
update2(lson, l, r , w);
return;
}
if( l > m ){
update2(rson, l, r , w);
return;
}
update2(lson, l, m , w);
update2(rson, m+1, r, w);
}
int n,Q;
char buf[100];
int main()
{
while(~scanf("%d %d",&n,&Q)){
init(1, 1, n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
update(1, i, x);
}
for(int i=0;i<Q;i++){
scanf("%s",buf);
int l,r;
scanf("%d%d",&l,&r);
if(buf[0] == 'r'){
ll ans = querys(1, l, r);
update2(1, l, r, 0);
printf("%lld\n",ans);
}else{
int w;
scanf("%d",&w);
update(1, l, r, w);
}
}
}
return 0;
}
/*
5 4
1 2 3 4 5
r 1 5
a 1 5 1
r 5 5
*/