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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
#define ll __int64
#define INF 0x3fffffff
using namespace std;

struct Node
{
    int l,r;
    int Max,Sum;
    int Mid(){
        return (l+r)/2;
    }
}tree[400000];

void BuildTree(int root,int l,int r)
{
    tree[root].Max=-INF;
    tree[root].Sum=0;
    tree[root].l=l;
    tree[root].r=r;
    if(l!=r)
    {
        BuildTree(2*root+1,l,(l+r)/2);
        BuildTree(2*root+2,(l+r)/2+1,r);
    }
}

void Insert(int root,int i,int v)
{
    if(tree[root].l==tree[root].r)
    {
        tree[root].Max=tree[root].Sum=v;
        return;
    }
    if(i<=tree[root].Mid())
    {
        Insert(2*root+1,i,v);
    }
    else
    {
        Insert(2*root+2,i,v);
    }
    tree[root].Max=max(tree[2*root+1].Max,tree[2*root+2].Max);
    tree[root].Sum=tree[2*root+1].Sum+tree[2*root+2].Sum;
}

int QuerySum(int root,int l,int r)
{
    if(tree[root].l==l&&tree[root].r==r){
        return tree[root].Sum;
    }
    if(r<=tree[root].Mid()){
        return QuerySum(2*root+1,l,r);
    }else if(l>tree[root].Mid()){
        return QuerySum(2*root+2,l,r);
    }else{
        return QuerySum(2*root+1,l,tree[root].Mid())+QuerySum(2*root+2,tree[root].Mid()+1,r);
    }
}

int QueryMax(int root,int l,int r)
{
    if(tree[root].l==l&&tree[root].r==r){
        return tree[root].Max;
    }
    if(r<=tree[root].Mid()){
        return QueryMax(2*root+1,l,r);
    }else if(l>tree[root].Mid()){
        return QueryMax(2*root+2,l,r);
    }else{
        return max(QueryMax(2*root+1,l,tree[root].Mid()),QueryMax(2*root+2,tree[root].Mid()+1,r));
    }
}

int main()
{
    //freopen("d:\\Test.txt","r",stdin);
	int n,m;
	cin>>n>>m;
	BuildTree(0,1,n);
	for(int i=1;i<=n;i++)
	{
	    int value;
	    cin>>value;
	    Insert(0,i,value);
	}
	for(int i=0;i<m;i++)
	{
	    int p,x,y;
	    cin>>p>>x>>y;
	    if(p==1){
	        Insert(0,x,y);
	    }else if(p==2){
	        cout<<QuerySum(0,x,y)<<endl;
	    }else if(p==3){
	        cout<<QueryMax(0,x,y)<<endl;
	    }
	}
	return 0;
}

时间: 2024-10-26 05:21:01

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

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

赤裸裸的线段树 #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 bui

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

题目传送:操作格子 思路:简单线段树,单点更新,区间求和以及最值 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都需要给出回答,聪