您的位置:首页 > 其它

蓝桥杯_ 算法训练 操作格子

2018-03-23 10:40 441 查看
问题描述有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或3的操作总数。
每行1个整数,对应了每个p=2或3操作的结果。
样例输入4 3
1 2 3 4
2 1 3
1 4 3
3 1 4样例输出6
3数据规模与约定对于20%的数据n <= 100,m <= 200。
对于50%的数据n <= 5000,m <= 5000。
对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。

线段树的操作,开始想用lazy来着,后来发现根本就没有区间的加减更新,所以后来就把lazy去掉了。但是还是带有lazy的线段树比较好一些,虽然在这个题里面用处不是很大。#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <cmath>
#include <math.h>
#define INF 0x3f3f3f3f
#define Lson L,mid,rt<<1
#define Rson mid+1,R,rt<<1|1

using namespace std;
typedef long long ll;
const int MAXN = 100100;
int n,m;
struct Node
{
int sum,lazy,max_num;
}T[MAXN<<2];

void Pushup(int rt)
{
T[rt].sum = T[rt<<1].sum + T[rt<<1|1].sum;
T[rt].max_num = max(T[rt<<1].max_num,T[rt<<1|1].max_num);
}

void Build(int L,int R,int rt)
{
if(L==R)
{
scanf("%d",&T[rt].sum);
T[rt].max_num = T[rt].sum;
return ;
}
int mid = (L+R) >>1;
Build(Lson);
Build(Rson);
Pushup(rt);
}

//void PushDown(int L,int R,int rt)
//{
// int mid = (L+R) >> 1;
// T[rt<<1].sum = T[rt].lazy * (mid - L +1);
// T[rt<<1|1].sum = T[rt].lazy * (R-mid);
// T[rt<<1].lazy = T[rt].lazy;
// T[rt<<1|1].lazy = T[rt].lazy;
// T[rt].lazy = 0;
//}

void Init()
{
scanf("%d%d",&n,&m);
Build(1,n,1);
}

int Query(int l,int r,int L,int R,int rt)
{
if(l == L && r == R)
return T[rt].sum;
int mid = (L+R)>>1;
// if(T[rt].lazy)
// PushDown(L,R,rt);
if(r <= mid)
return Query(l,r,Lson);
else if (l > mid)
return Query(l,r,Rson);
return Query(l,mid,Lson) + Query(mid+1, r, Rson);
}

int get_max(int l,int r,int L,int R,int rt)
{
if(l == L && r == R)
return T[rt].max_num;
int mid = (L+R)>>1;
// if(T[rt].lazy)
// PushDown(L,R,rt);
if(r<=mid)
return get_max(l,r,Lson);
else if(l > mid)
return get_max(l,r,Rson);
return max(get_max(l,mid,Lson),get_max(mid+1,r,Rson));
}

void Updata(int l,int r,int L,int R,int rt,int v)
{
if(l == L && r == R)
{
// T[rt].lazy = v;
T[rt].max_num = v;
T[rt].sum = v;
return ;
}
int mid = (L+R) >> 1;
// if(T[rt].lazy)
// PushDown(L,R,rt);
if(r<=mid)
Updata(l,r,Lson,v);
else if (l > mid)
Updata(l,r,Rson,v);
else
{
Updata(l,mid,Lson,v);
Updata(mid+1,r,Rson,v);
}
Pushup(rt);
}

void Solve()
{
int a,b,c;
for(int i =0 ;i < m;i ++)
{
scanf("%d%d%d",&a,&b,&c);
if(a == 2)
printf("%d\n",Query(b,c,1,n,1));
if(a == 3)
printf("%d\n",get_max(b,c,1,n,1));
if(a == 1)
Updata(b,b,1,n,1,c);
}
}
int main()
{
Init();
Solve();
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  蓝桥杯 线段树