蓝桥杯操作格子(线段树)

赤裸裸的线段树

#include<iostream>
#include<cstdio>
#include<algorithm>
#define Max(a,b) (a>b)?a:b
using namespace std;
const int MAX_N=100005*4;//至少要开2*n-1个空间
typedef long long LL;
struct node{
    int l,r,max;
    LL sum;
};
node a[MAX_N];
void build(int n,int l,int r)
{
    a[n].l=l;
    a[n].r=r;
    a[n].max=-1;
    a[n].sum=0;
    if(l==r)
    {
        return ;
    }
    build(2*n,l,(l+r)/2);
    build(2*n+1,(l+r)/2+1,r);
}
void insert(int n, int pos,int val)
{
    a[n].sum+=val;
    a[n].max=max(a[n].max,val);
    if(a[n].l==pos&&a[n].r==pos)
    {
        return ;
    }
    int mid=(a[n].l+a[n].r)/2;
    if(pos<=mid)
        insert(2*n,pos,val);
    else
        insert(2*n+1,pos,val);
}
void change(int n,int pos,int val)
{
    if(a[n].l==pos&&a[n].r==pos)
    {
        a[n].max=val;
        a[n].sum=val;
        return ;
    }
    int mid=(a[n].l+a[n].r)/2;
    if(pos<=mid)
        change(2*n,pos,val);
    else
        change(2*n+1,pos,val);
    a[n].max=max(a[2*n].max,a[2*n+1].max);
    a[n].sum=a[2*n].sum+a[2*n+1].sum;
}
int Qmax(int n,int l,int r)
{
    if(a[n].l==l&&a[n].r==r)
    {
        return a[n].max;
    }
    int mid=(a[n].l+a[n].r)/2;
    if(r<=mid)
    {
        return Qmax(2*n,l,r);
    }
    else if(mid<l)
    {
        return Qmax(2*n+1,l,r);
    }
    else
    {
        return Max(Qmax(2*n,l,mid),Qmax(2*n+1,mid+1,r));
    }
}

LL Qsum(int n,int l, int r)
{
    if(a[n].l==l&&a[n].r==r)
    {
        return a[n].sum;
    }
    int mid=(a[n].l+a[n].r)/2;
    if(r<=mid)
    {
        return Qsum(2*n,l,r);
    }
    else if(l>mid)
    {
        return Qsum(2*n+1,l,r);
    }
    return Qsum(2*n,l,mid)+Qsum(2*n+1,mid+1,r);
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    build(1,1,n);
    for(int i=1;i<=n;i++)
    {
        int v;
        scanf("%d",&v);
        insert(1,i,v);
    }
    while(m--)
    {
        int op,x,y;
        scanf("%d %d %d",&op,&x,&y);
        switch(op)
        {
            case 1:{
                change(1,x,y);
                break;
            }
            case 2:{
                printf("%lld\n",Qsum(1,x,y));
                break;
            }
            case 3:{
                printf("%d\n",Qmax(1,x,y));
                break;
            }
        }
    }

    return 0;
}
时间: 2024-08-24 15:46:57

蓝桥杯操作格子(线段树)的相关文章

蓝桥杯-操作格子(线段树)

#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<set> #include<map> #include<vector> #include<cmath> #define ll __int64 #define

蓝桥杯 - 操作格子 (线段树)

题目传送:操作格子 思路:简单线段树,单点更新,区间求和以及最值 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map>

蓝桥杯 算法训练 操作格子 [ 线段树 ]

传送门 算法训练 操作格子 时间限制:1.0s   内存限制:256.0MB 锦囊1 锦囊2 锦囊3 问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求出的结果. 输入格式 第一行2个整数n,m. 接下来一行n个整数表示n个格子的初始权值. 接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x

算法训练 操作格子 线段树板子题

问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求出的结果. 输入格式 第一行2个整数n,m. 接下来一行n个整数表示n个格子的初始权值. 接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值. 输出格式 有若干行,行数等于p=2

蓝桥杯Log大侠(线段树单点区间更新)

标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: 对其某个子序列的每个整数变为: [log_2 (x) + 1]  其中 [] 表示向下取整,就是对每个数字求以2为底的对数,然后取下整.     例如对序列 3 4 2 操作一次后,这个序列会变成 2 3 2.         drd需要知道,每次这样操作后,序列的和是多少. [输入格式] 第一行

2333: [SCOI2011]棘手的操作[离线线段树]

2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2325  Solved: 909[Submit][Status][Discuss] Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权值增加v A2 x v: 将第x个节点所在的连通块的所有

Sereja and Array-数组操作或者线段树或树状数组

CodeForces - 315B Sereja and Array Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description Sereja has got an array, consisting of n integers, a1,?a2,?...,?an. Sereja is an active boy, so he is now going

uva 1401 Fast Matrix Operations 快速矩阵操作 (线段树 区间修改和查询)

题意:给一个r行c列的全0矩阵,支持以下三种操作: 1 x1 y1 x2 y2 v 子矩阵(x1 y1 x2 y2)的所有元素增加v 2 x1 y1 x2 y2 v 子矩阵(x1 y1 x2 y2)的所有元素设为v 3 x1 y1 x2 y2   查询子矩阵(x1 y1 x2 y2)的元素和.最小值.最大值. 子矩阵(x1 y1 x2 y2)是指满足 x1 <= x <= x2, y1 <= y <= y2的所有元素(x,y). 矩阵不超过20行,矩阵总元素可多达10^6个. 思路

BZOJ_1858_[Scoi2010]序列操作_线段树

Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总共有多少个1 4 a b 询问[a, b]区间内最多有多少个连续的1 对于每一种询问操作,lxhgww都需要给出回答,聪