杭电多校第一场 线段树模板题 Naive Operations

题目描述

In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for al,al+1...ar
2. query l r: query 

输入

There are multiple test cases, please read till the end of input file.
For each test case, in the first line, two integers n,q, representing the length of a,b and the number of queries.
In the second line, n integers separated by spaces, representing permutation b.
In the following q lines, each line is either in the form 'add l r' or 'query l r', representing an operation.
1≤n,q≤100000, 1≤l≤r≤n, there're no more than 5 test cases.

输出

Output the answer for each 'query', each one line.

样例输入

5 12
1 5 2 4 3
add 1 4
query 1 4
add 2 5
query 2 5
add 3 5
query 1 5
add 2 4
query 1 4
add 2 5
query 2 5
add 2 2
query 1 5

样例输出

1
1
2
4
4
6

线段树还是一知半解,会套用而已,先记下吧,防止自己忘记(虽说是参考的大佬的)

#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxx=100050;
struct node
{
    int l,r,lz,mn;
    ll sum;
}tree[maxx<<2];
int b[maxx];
void pushup(int i)
{
    tree[i].mn=min(tree[i<<1].mn,tree[i<<1|1].mn);
    tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
}
void pushdown(int i)
{
    tree[i<<1].mn-=tree[i].lz;
    tree[i<<1|1].mn-=tree[i].lz;
    tree[i<<1].lz+=tree[i].lz;
    tree[i<<1|1].lz+=tree[i].lz;
    tree[i].lz=0;
}
void build(int i,int l,int r)
{
    tree[i].l=l;
    tree[i].r=r;
    tree[i].lz=0;
    tree[i].sum=0;
    if(l==r)
    {
        tree[i].mn=b[l];
        return;
    }
    int mid=(l+r)/2;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    pushup(i);
}
void modify(int i,int l,int r)
{
    if(tree[i].l==l&&tree[i].r==r)
    {
        if(tree[i].mn>1)
        {
            tree[i].mn--;
            tree[i].lz++;
            return;
        }
    }
    if(tree[i].l==tree[i].r)
    {
        tree[i].mn=b[tree[i].l];
        tree[i].sum+=1;
        return;
    }
    int mid=(tree[i].l+tree[i].r)/2;
    if(tree[i].lz)
    {
        pushdown(i);
    }
    if(r<=mid)
    {
        modify(i<<1,l,r);
    }
    else if(l>mid)
    {
        modify(i<<1|1,l,r);
    }
    else
    {
        modify(i<<1,l,mid);
        modify(i<<1|1,mid+1,r);
    }
    pushup(i);
}
ll query(int i,int l,int r)
{
    if(tree[i].l==l&&tree[i].r==r)
    {
        return tree[i].sum;
    }
    int mid=(tree[i].l+tree[i].r)/2;
    if(r<=mid)
    {
        return query(i<<1,l,r);
    }
    else if(l>mid)
    {
        return query(i<<1|1,l,r);
    }
    else
    {
        return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
    }
}
int main()
{
    int n,q;
    while(scanf("%d %d",&n,&q)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&b[i]);
        }
        build(1,1,n);
        char op[20];
        int l,r;
        while(q--)
        {
            scanf("%s %d %d",op,&l,&r);
            if(op[0]=='a')
            {
                modify(1,l,r);
            }
            else
            {
                printf("%lld\n",query(1,l,r));
            }
        }
    }
    return 0;
}
具体可参考:https://blog.csdn.net/SunMoonVocano/article/details/81207676

猜你喜欢

转载自blog.csdn.net/weixin_41370251/article/details/81325614