算法训练 操作格子
算法训练 操作格子
时间限制:1.0s 内存限制:256.0MB
问题描述
有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
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
3
数据规模与约定
对于20%的数据n <= 100,m <= 200。
对于50%的数据n <= 5000,m <= 5000。
对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。
#include<iostream> #include<cstdio> #define maxn 500004 struct node { int left,right; int num; }tree[3*maxn]; int maxv[2*maxn]; int out=0; int max(int x,int y) { if(x>y) return x; else return y; } void build(int left,int right,int i) { tree[i].left=left; tree[i].right=right; tree[i].num=0; if(tree[i].left==tree[i].right) return ; int mid=(left+right)/2; build(left,mid,2*i); build(mid+1,right,2*i+1); } void insert(int id,int i,int j) { if(tree[id].left==i&&tree[id].right==i) { tree[id].num=j; maxv[id]=j; } if(tree[id].left==tree[id].right) return ; if(i>tree[id].right) return; if(i<tree[id].left) return; int mid=(tree[id].left+tree[id].right)/2; if(i<=mid) insert(id*2,i,j); else insert(id*2+1,i,j); tree[id].num=tree[2*id].num+tree[2*id+1].num; maxv[id]=max(maxv[id*2],maxv[id*2+1]); } void sum(int id,int i,int j) { int mid=(tree[id].left+tree[id].right)/2; if(tree[id].left==i&&tree[id].right==j) { out+=tree[id].num; return ; } if(j<=mid) sum(id*2,i,j); else if(i>mid) sum(id*2+1,i,j); else { sum(id*2,i,mid); sum(id*2+1,mid+1,j); } } int query(int id,int l,int r) { int mid=(tree[id].left+tree[id].right)/2; int ans=0; if(l==tree[id].left&&r==tree[id].right) { return maxv[id]; } if(r<=mid) ans=max(ans,query(id*2,l,r)); else if(l>mid) ans=max(ans,query(id*2+1,l,r)); else { ans=max(ans,query(id*2,l,mid)); ans=max(ans,query(id*2+1,mid+1,r)); } return ans; } int main() { int i,p,x,y; int n,m,u; while(~ scanf("%d%d",&n,&m)) { build(1,n,1); for(i=1;i<=n;i++) { scanf("%d",&u); insert(1,i,u); } for(i=1;i<=m;i++) { scanf("%d%d%d",&p,&x,&y); if(p==1) insert(1,x,y); if(p==2) { sum(1,x,y); printf("%d\n",out); out=0; } if(p==3) { printf("%d\n",query(1,x,y)); } } } return 0; }