poj 3468 小白算法练习 a simple problem with integers 线段树
来源:互联网 发布:简历淘宝美工工作描述 编辑:程序博客网 时间:2024/06/07 06:19
A Simple Problem with Integers
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4
Sample Output
455915
Hint
线段树模板:
//线段树最起码包括三个步骤
//1、构造
//2、搜索 | 查找
//3、更新
int MAX=1000;
struct threadtree{
int val;
};
threadtree tt[MAX];
/*
root:线段树的根节点
arr:用来构造线段树的数组
start:数组的起始位置
end:数组的结束位置
*/
//构造
void build(int root,int arr[],int start,int end){
//如果是叶子节点
if(start==end){
tt[root].val=arr[start];
}
else
{
int mid=(start+end)/2;
build(root*2+1,arr,start,mid);
build(root*2+2,arr,mid+1,end);
//那么这里是 不是叶子节点的节点取最小值
tt[root].val=min(tt[root+1].val,tt[root+2].val);
}
}
/*
s_start:想要查找起点
s_end:想要查找终点
c_start:正在查找线段树的起点
c_end:正在查找线段树的终点
*/
//搜索 | 查找
int search(int root,int s_start,int s_end,int c_start,int c_end){
//查询区间与当前区间没有交集
if(s_start>c_end || s_end<c_start )
return INT_MAX;
//查询区间如果大于当前区间
if(s_start<=t_start && s_end>=c_end)
{
return tt[root].val;
}
//查询区间如果小于当前区间就往子树下面搜
int mid=(c_start+c_end)/2;
//合并区间,因为不可能正正好好的在同一颗子树上
return min(search(root*2+1,s_start,s_end,c_start,mid),search(root*2+2,s_start,s_end,mid+1,c_end));
}
//首先是单节点更新 --- 单节点更新过后说的是更新单片叶子,叶子更新过后要更新父节点
/*
c_start:当前线段树的起点
c_end:当前的线段树的终点
index:arr数组中的改变值的下标
doval:想要增加或改变的值
*/
void update(int root,int c_start,int c_end,int index,int doval){
//index与start相同时就代表找到了
if(c_start==c_end){
if(c_start==index)
tt[root].val+=doval;
return;
}
int mid=(c_start+c_end)/2;
if(index<=mid) update(root*2+1,c_start,mid,index,doval);
else update(root*2+2,mid+1,c_end,index,doval);
tt[root].val=min(tt[root*2+1].val,tt[root*2+2].val);
}
//区间更新【延迟标记还是挺难理解的】
const int MAX=1000;
struct threadtree{
int val;
int addval;//延迟标记
};
threadtree[MAX];
void push_down(int root){
if(tt[root].addval!=0){
tt[root*2+1].addval+=tt[root].addval;
tt[root*2+2].addval+=tt[root].addval;
tt[root*2+1].val+=tt[root].addval;
tt[root*2+2].val+=tt[root].addval;
tt[root].addval=0;
}
}
void build(int root,int arr[],int start,int end){
tt[root].addval=0;//延迟标记初始化为0
if(start==end){
tt[root].val=arr[start];
return;
}
else{
int mid=(start+end)/2;
build(root*2+1,arr,start,mid);
build(root*2+2,arr,mid+1,end);
tt[root].val=min(tt[root*2+1].val,tt[root*2+2].val);
}
}
int search(int root,int start,int end,int c_start,int c_end){
if(start>c_end || end<c_start){
return INT_MAX;
}
if(start<=c_start && end>=c_end){
return tt[root].val;
}
push_down(root);
int mid=(c_start+c_end)/2;
return min(search(root*2+1,start,end,c_start,mid),search(root*2+2,start,end,mid,c_end));
}
int update(int root,int start,int end,int c_start,int c_end,int addval){
if(start>c_end || end<c_start){
return INT_MAX;
}
if(start<=c_start && end>=c_end){
tt[root].addval+=addval;
tt[root].val+=addval;
return;
}
push_down(root);
int mid=(c_start+c_end)/2;
update(root*2+1,start,mid,c_start,c_end,addval);
update(root*2+2,mid+1,end,c_start,c_end,addval);
tt[root].val=min(tt[root*2+1].val,tt[root*2+2].val);
}
代码:
#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int MAX=100005;struct tree{long long val;long long mark;}segtree[MAX*4+1];long long sum(long long a,long long b){ //long long !!我被搞了很久return a+b;}void push_down(int root,int range){if(segtree[root].mark!=0){segtree[root*2+1].mark+=segtree[root].mark;segtree[root*2+2].mark+=segtree[root].mark;segtree[root*2+1].val+=(range-(range/2))*segtree[root].mark;//***//segtree[root*2+2].val+=(range/2)*segtree[root].mark;//***//segtree[root].mark=0;}}void build(int root,int arr[],int start,int end){segtree[root].mark=0;if(start==end){segtree[root].val=arr[start];return;}else{int mid=(start+end)/2;build(root*2+1,arr,start,mid);build(root*2+2,arr,mid+1,end);segtree[root].val=sum(segtree[root*2+1].val,segtree[root*2+2].val);}}long long search(int root,int start,int end,int c_start,int c_end){if(start>c_end || end<c_start) return 0;if(start<=c_start && end>=c_end){return segtree[root].val;}push_down(root,c_end-c_start+1);//***//int mid=(c_start+c_end)/2;return sum(search(root*2+1,start,end,c_start,mid),search(root*2+2,start,end,mid+1,c_end));}void update(int root,int start,int end,int c_start,int c_end,int add){if(start>c_end || end<c_start) return;if(start<=c_start && end>=c_end){segtree[root].mark+=add;segtree[root].val+=(c_end-c_start+1)*add;//***//return;}push_down(root,c_end-c_start+1);//***//int mid=(c_start+c_end)/2;update(root*2+1,start,end,c_start,mid,add);update(root*2+2,start,end,mid+1,c_end,add);segtree[root].val=sum(segtree[root*2+1].val,segtree[root*2+2].val);} int main(){//freopen("E:1001.txt","r",stdin);int N,Q;//数组N个数,输入N个数;Q次操作cin>>N>>Q;int arr[MAX];char str[5]="";for(int i=1;i<=N;i++){cin>>arr[i];}build(0,arr,1,N);for(int i=1;i<=Q;i++){cin>>str;if(strcmp(str,"Q")==0){int s,e;cin>>s>>e;cout<<search(0,s,e,1,N)<<endl;}else{int s,e,add;cin>>s>>e>>add;update(0,s,e,1,N,add);}}}
- 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(线段树)
- 【css】浏览器私有属性前缀使用详解
- 01--机器学习之决策树
- 推荐学习方法——费曼技巧,以教促学,教学相长
- JAVA中的Session
- 悬浮透明框
- poj 3468 小白算法练习 a simple problem with integers 线段树
- Python函数的参数
- Android 三类动画
- PyCharm Professional 2016 破解
- 一些常规形几何形状的绘制和效果填充(一)
- PAT B1043. 输出PATest
- 2017暑假训练第一场的一些题目
- 网络流基础算法模板
- 欢迎使用CSDN-markdown编辑器