poj 3468 A Simple Problem with Integers
来源:互联网 发布:电视视频端口坏掉 编辑:程序博客网 时间:2024/06/06 07:01
题目大意:给你一串数字,和一堆询问,分别是问一段区间的和,和给某段数字每个数字增加一定的值。
解题思路:用暴力做肯定会超时,所以用线段树或者树状数组都可以做。这里为了练习线段树就用线段树做了。
线段树的思路就是将当前区间二分成一颗二叉树,通过区间的合并和分解来实现对区间值的修改。
做出来的第一个线段树,纪念一下。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;__int64 n,q;__int64 num[100100];char c[10];__int64 x,y,z,ans;struct PPP{ __int64 l,r,sum,lazy;}tree[210000];__int64 tail;void build(__int64 k,__int64 s,__int64 t){ tree[k].lazy=0; __int64 mid = (s+t)/2; if (s == t) { tree[k].sum = num[s]; return; } tail++; tree[k].l = tail; build(tail,s,mid); tail++; tree[k].r = tail; build(tail,mid+1,t); tree[k].sum = tree[tree[k].l].sum+tree[tree[k].r].sum; return;}//求某一段数的和 __int64 find(__int64 s,__int64 t,__int64 k,__int64 ss,__int64 tt){ __int64 mid = (ss+tt)/2; if (ss != tt) { tree[tree[k].l].lazy += tree[k].lazy; tree[tree[k].r].lazy += tree[k].lazy; } tree[k].sum += (tt-ss+1) * tree[k].lazy; tree[k].lazy = 0; if (s==ss&&t==tt) { return tree[k].sum; } if (s>=mid+1){ return find(s,t,tree[k].r,mid+1,tt); } if (t<=mid) { return find(s,t,tree[k].l,ss,mid); } return find(s,mid,tree[k].l,ss,mid)+find(mid+1,t,tree[k].r,mid+1,tt);}//改变某段数的值 void change(__int64 s,__int64 t,__int64 k,__int64 ss,__int64 tt,__int64 temp){ __int64 mid = (ss+tt)/2; if (ss != tt) { tree[tree[k].l].lazy += tree[k].lazy; tree[tree[k].r].lazy += tree[k].lazy; } tree[k].sum += (tt-ss+1) * tree[k].lazy; tree[k].lazy = 0; if (s==ss&&t==tt) { tree[k].lazy += temp; return; } else { tree[k].sum += (t-s+1) * temp; } if (s>=mid+1){ change(s,t,tree[k].r,mid+1,tt,temp); return; } if (t<=mid) { change(s,t,tree[k].l,ss,mid,temp); return; } change(s,mid,tree[k].l,ss,mid,temp); change(mid+1,t,tree[k].r,mid+1,tt,temp); return;}//查找某一个数的值 void work(__int64 k,__int64 s,__int64 t){ __int64 mid = (s+t)/2; if (s == t) { //printf("!!!!%I64d %I64d\n",s,tree[k].sum+tree[k].lazy); return; } work(tree[k].l,s,mid); work(tree[k].r,mid+1,t);}int main(){ scanf("%I64d%I64d",&n,&q); for (__int64 i = 1; i <= n ; i ++) scanf("%I64d",&num[i]); tail = 1; build(1,1,n); for (__int64 i = 1 ; i <= q ; i ++) { scanf("%s",c); if (c[0] == 'Q') { scanf("%I64d%I64d",&x,&y); ans = find(x,y,1,1,n); printf("%I64d\n",ans); } if (c[0] == 'C') { scanf("%I64d%I64d%I64d",&x,&y,&z); change(x,y,1,1,n,z); } } //system("pause"); return 0;}
- POJ 3468 A Simple Problem With Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ-3468-A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 - A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- [C#]TreeView控件使用之磁盘目录查看器
- Effective C++ 读书总结
- Can You Crack?
- C++开发者都应该使用的10个C++11特性
- [C]计算机图形学实验三
- poj 3468 A Simple Problem with Integers
- 如果你想学好C#,请保持一下良好心态!!
- [转载]PHP页面之间传递参数的四种方式
- Viual Studio 2010 Directx开发环境配置
- [C++]三维图形旋转-矩阵
- PL/0语言功能扩展[PASCAL VERSION]
- 【编译原理】实验1.词法分析
- wp7实现定时刷新(计时器)
- Windows Phone 7 Bugs