蓝桥杯 操作格子(线段树)
2014-04-03 21:27
387 查看
问题描述
有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。
思路:
线段树的基本用法, 详情请百度。(可作为线段树模板), nyoj上的士兵杀敌(三)居然用线段树过不了, 看样线段树并没有想象中的快。。。
有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。
思路:
线段树的基本用法, 详情请百度。(可作为线段树模板), nyoj上的士兵杀敌(三)居然用线段树过不了, 看样线段树并没有想象中的快。。。
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct Node { int left, right, max, sum; struct Node *lchild, *rchild; }node; int mymax(int a, int b) { return a > b ? a : b; } void modify(node *p, int src, int val) { if(p->left == src && p->right == src) { p->max = val; p->sum = val; return; } else { int mid = (p->left+p->right) / 2; if(src <= mid) { modify(p->lchild, src, val); } else if(src > mid) { modify(p->rchild, src, val); } p->max = mymax(p->lchild->max, p->rchild->max); p->sum = p->lchild->sum + p->rchild->sum; } } node *createtree(int left, int right) { node *p = (node *)malloc(sizeof(node)); p->left = left; p->right = right; p->max = 0; p->sum = 0; p->lchild = NULL; p->rchild = NULL; if(left < right) { int mid = (left + right) / 2; p->lchild = createtree(left, mid); p->rchild = createtree(mid+1, right); } return p; } void insert(node *p, int src, int val) { p->sum += val; p->max = mymax(p->max, val); if(p->left == p->right) { return; } else { int mid = (p->left+p->right) / 2; if(src <= mid) { insert(p->lchild, src, val); } else { insert(p->rchild, src, val); } } } int getmax(node *p, int left, int right) { if(p->left == left && p->right == right) { return p->max; } else { int mid = (p->left+p->right) / 2; if(right <= mid) { return getmax(p->lchild, left, right); } else if(left > mid) { return getmax(p->rchild, left, right); } else { return mymax(getmax(p->lchild, left, mid), getmax(p->rchild, mid+1, right)); } } } int getsum(node *p, int left, int right) { if(p->left == left && p->right == right) { return p->sum; } else { int mid = (p->left+p->right) / 2; if(right <= mid) { return getsum(p->lchild, left, right); } else if(left > mid) { return getsum(p->rchild, left, right); } else { return getsum(p->lchild, left, mid) + getsum(p->rchild, mid+1, right); } } } int main() { int n, m, t, x, y, i, val; node *p = NULL; scanf("%d%d", &n, &m); p = createtree(1, n); for(i = 1; i <= n; i++) { scanf("%d", &val); insert(p, i, val); } for(i = 0; i < m; i++) { scanf("%d%d%d", &t, &x, &y); switch(t) { case 1: modify(p, x, y); break; case 2: printf("%d\n", getsum(p, x, y)); break; case 3: printf("%d\n", getmax(p, x, y)); break; } } return 0; }
相关文章推荐
- SAMSUNG三星停产SDRAM 及替换品牌型号推荐
- 例说SQL Server 2008 日期和时间函数
- JS日期类函数
- Ubuntu 13.04 开启root 登录 ,设置root 密码
- ubuntu下安装和配置java开发环境
- Zynq7020 ubuntu下开发(1)
- 通过实现一个TableView来理解iOS UI编程
- static_cast、dynamic_cast、reinterpret_cast、const_cast以及C强制类型转换的区别
- Guid.NewGuid().ToString()得几种参数
- 第六周(项目四)——静态成员应用。
- R语言进阶之3:数据汇总/透视/提炼
- 写的很好 链表的各种题目整理(C语言实现)
- 第10-11章: jQuery各个版本的变化及jQuery性能优化和技巧---目录
- struts2零配置详解(struts-Convention-plugin)
- 恩 很好
- 常用目录
- JFrame功能简述 java
- 关于android交互设计的那点事
- poj 2486(树形dp)
- 推荐文章