操作格子
来源:互联网 发布:雅思考试经验知乎 编辑:程序博客网 时间:2024/04/28 03:07
问题描述
有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。
由于数据量比较大,所以暴力解决的话肯定超时,对于区间来说,可以用线段树,logn
#include <iostream>using namespace std;int nmax=-1;int nsum=0;int nnode=0;struct cnode{ cnode *left;cnode *right; int l ,r; int e,sum,max; }tree[400011]; void Build(cnode *root,int l,int r){ root->l=l;root->r=r;root->max=-1;root->e=root->sum=0; if(l!=r){ nnode++;root->left=tree+nnode;Build(root->left,l,(l+r)/2); nnode++;root->right=tree+nnode;Build(root->right,(l+r)/2+1,r); }}void Insert(cnode *root,int i,int p){ root->sum+=p; if(root->max<p) root->max=p; if(root->l==root->r&&root->l==i) { /* root->e=p; root->max=p; root->sum=p; */ return ; }// cout<<root->sum; if(i<=(root->l+root->r)/2) Insert(root->left,i,p); else Insert(root->right,i,p);}int Query(cnode *root,int l,int r){ if(root->l==l&&root->r==r) { return root->sum; } if(l>=(root->l+root->r)/2+1) return Query(root->right,l,r); else if(r<=(root->l+root->r)/2) return Query(root->left,l,r); else return Query(root->left,l,(root->l+root->r)/2)+Query(root->right,(root->l+root->r)/2+1,r);}void QueryMax(cnode *root,int l,int r){ if(root->l==l&&root->r==r) { if(root->max>nmax) nmax=root->max; return ; } if(l>=(root->l+root->r)/2+1) QueryMax(root->right,l,r); else if(r<=(root->l+root->r)/2) QueryMax(root->left,l,r); else { QueryMax(root->left,l,(root->l+root->r)/2); QueryMax(root->right,(root->l+root->r)/2+1,r);}}void Fix(cnode *root,int i,int p){ if(root->l==root->r&&root->l==i) { root->e=p; root->max=p; root->sum=p; return ; } if(i<=(root->l+root->r)/2) Fix(root->left,i,p); else Fix(root->right,i,p); root->sum=root->left->sum+root->right->sum; if(root->left->max>root->right->max) root->max=root->left->max; else root->max=root->right->max;}int main(int argc, char** argv) { int i,n,t,p,q,r; cin>>n>>t; Build(tree,1,n); for(i=1;i<=n;i++) { cin>>p; Insert(tree,i,p); } for(i=1;i<=t;i++) { cin>>p>>q>>r; if(p==1)Fix(tree,q,r); if(p==2){ cout<<Query(tree,q,r)<<endl; } if(p==3){ QueryMax(tree,q,r); cout<<nmax<<endl; nmax=-1; } } return 0;}
0 0
- 操作格子
- 格子操作
- 操作格子
- 操作格子
- 操作格子
- 操作格子
- 操作格子
- 操作格子
- 操作格子
- 蓝桥杯:操作格子
- c语言 操作格子
- 算法训练 操作格子
- 算法训练 操作格子
- 操作格子 线段树
- 算法训练 操作格子
- 操作格子(线段树)
- 算法训练 操作格子
- 蓝桥杯之操作格子
- MySQL存储过程学习
- 长连接和短连接的区别
- matlab中的bwlabel函数
- 无法读取tomcat输出流的问题
- QMap QHash的选择
- 操作格子
- 查询2个list相同和不相同元素
- QT开发:QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection'...
- mac_tips
- Spring AOP原理及拦截器
- Java编码规范
- 基于递归思想的组合、H变换等几个算法实现
- gridview单元格操作
- (转)机器视觉方向的大牛介绍