蓝桥杯_ 算法训练 操作格子
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;
}
共有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;
}
相关文章推荐
- 蓝桥杯 算法训练 操作格子 [ 线段树 ]
- 蓝桥杯 算法训练 操作格子
- 蓝桥杯 算法训练 操作格子 JAVA
- 蓝桥杯 算法训练 操作格子 (最基本的线段树)
- 蓝桥杯 算法训练 操作格子
- 蓝桥杯 算法训练 操作格子(线段树,点更新)
- 蓝桥杯-算法训练--ALGO-8 操作格子
- 蓝桥杯_算法训练_操作格子
- 蓝桥杯 算法训练 操作格子 (线段树)
- 蓝桥杯算法训练——操作格子(线段树+单点更新+区间求和+求最大值)
- 算法-蓝桥杯-算法训练 操作格子(C++)
- 蓝桥杯 算法训练 操作格子(线段树)
- [蓝桥杯]算法训练 操作格子-链式线段树
- 蓝桥杯 算法训练 操作格子
- 蓝桥杯 算法训练 操作格子
- 蓝桥杯 算法训练 操作格子 (线段树模板)
- 蓝桥杯算法训练_格子操作_线段树_区间和与区间最值
- 蓝桥杯 ALGO-8 算法训练 操作格子(线段树)
- 蓝桥杯-算法训练 操作格子
- 算法训练 操作格子