poj 3468 线段数 修改区间(点)
2012-07-17 15:35
218 查看
主要是修改区间的时候要维护线段数。。
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
Sample Output
还有一道杭电上的题目:
一样的类型,这次是修改点:
Total Submission(s) : 11 Accepted Submission(s) : 6
[align=left]Problem Description[/align]
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
[align=left]Input[/align]
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
[align=left]Output[/align]
对于每一次询问操作,在一行里面输出最高成绩。
[align=left]Sample Input[/align]
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5
[align=left]Sample Output[/align]
5
6
5
9
View Code
A Simple Problem with Integers
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 31920 | Accepted: 9071 | |
Case Time Limit: 2000MS |
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 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
#include<iostream> #include<fstream> using namespace std; struct e{ int left,right; long long add; long long sum; }; e tree[400011]; long long a[100001]; long long build(int s,int t,int num){ //建树 long long i,j; tree[num].left=s; tree[num].right=t; tree[num].add=0; if(s!=t) { i=build(s,(s+t)/2,num*2); j=build((s+t)/2+1,t,num*2+1); } else { tree[num].sum=a[s]; return(a[s]); } tree[num].sum=i+j; return(tree[num].sum); } void insert(int s,int t,int add,int num){ if(s<=tree[num].left&&tree[num].right<=t) { tree[num].add+=add; tree[num].sum+=add*(tree[num].right-tree[num].left+1); return; } if(tree[num].add){ // 向下传递 tree[num*2].sum+=tree[num].add*(tree[num*2].right-tree[num*2].left+1); tree[num*2+1].sum+=tree[num].add*(tree[num*2+1].right-tree[num*2+1].left+1); tree[num*2].add+=tree[num].add; tree[num*2+1].add+=tree[num].add; tree[num].add=0; } if(s<=(tree[num].left+tree[num].right)/2) insert(s,t,add,num*2); if(t>(tree[num].left+tree[num].right)/2) insert(s,t,add,num*2+1); tree[num].sum=tree[num*2].sum+tree[num*2+1].sum; } long long search(int s,int t,int num){ long long i=0,j=0; if(s<=tree[num].left&&tree[num].right<=t) { return(tree[num].sum); } if(tree[num].add){ tree[num*2].sum+=tree[num].add*(tree[num*2].right-tree[num*2].left+1); tree[num*2+1].sum+=tree[num].add*(tree[num*2+1].right-tree[num*2+1].left+1); tree[num*2].add+=tree[num].add; tree[num*2+1].add+=tree[num].add; tree[num].add=0; } if(s<=(tree[num].left+tree[num].right)/2) { i=search(s,t,num*2); } if(t>(tree[num].left+tree[num].right)/2) { j=search(s,t,num*2+1); } return(i+j); } int main(){ //ifstream cin("in.txt"); int i,j,k,n,m,p,t; char s; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,n,1); for(i=1;i<=m;i++) { scanf("\n%c",&s); if(s=='C') { scanf("%d%d%d",&j,&k,&p); if(j>k) {t=j;j=k;k=t;} insert(j,k,p,1); } else { scanf("%d%d",&j,&k); if(j>k) {t=j;j=k;k=t;} cout<<search(j,k,1)<<endl; } } return(0); }
还有一道杭电上的题目:
一样的类型,这次是修改点:
I Hate It
Time Limit : 9000/3000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)Total Submission(s) : 11 Accepted Submission(s) : 6
[align=left]Problem Description[/align]
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
[align=left]Input[/align]
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
[align=left]Output[/align]
对于每一次询问操作,在一行里面输出最高成绩。
[align=left]Sample Input[/align]
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5
[align=left]Sample Output[/align]
5
6
5
9
View Code
#include <iostream> #include <stdio.h> #include <string.h> #define INF 0x3fffffff using namespace std; const int N=200010; struct Node{ int left,right; int max; }tree[N*4]; int a ; int max(int a,int b) { if(a>b) return a; return b; } void build(int s,int t,int r) { tree[r].left=s; tree[r].right=t; if(s==t) { tree[r].max=a[s]; return; } int mid=(s+t)/2; build(s,mid,r*2); build(mid+1,t,r*2+1); tree[r].max=max(tree[r*2].max,tree[r*2+1].max); //递归更新父节点 } void update(int s,int t,int a,int value,int r) // s、t、分别代表根节点为r的左右两范围 { if(tree[r].left==tree[r].right) { tree[r].max=value; return ; } if(a<=(s+t)/2) { update(s,(s+t)/2,a,value,r*2); } else update((s+t)/2+1,t,a,value,r*2+1); tree[r].max=max(tree[r*2].max,tree[r*2+1].max); //递归更新父节点 } int query(int s,int t, int r) { if(s<=tree[r].left && tree[r].right<=t) return tree[r].max; int m1=-INF,m2=-INF; if(s<=(tree[r].left+tree[r].right)/2) m1=query(s,t,r*2); if(t>(tree[r].left+tree[r].right)/2) m2=query(s,t,r*2+1); return max(m1,m2); } int main() { int n,m,i,j,p,q,f; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++) { scanf("\n%d",&a[i]); } build(1,n,1); getchar(); while(m--) { char ch; scanf("%c",&ch); if(ch=='Q') { scanf("%d%d",&p,&q); if(p>q) {f=p;p=q;q=f;} cout<<query(p,q,1)<<endl; } if(ch=='U') { scanf("%d%d",&p,&q); update(1,n,p,q,1); } getchar(); } } 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 块状链表 区间修改+区间查询
- poj 3468 线段树 区间内的线段和(成段更新)
- poj 3468 A Simple Problem with Integers【线段树区间修改】
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
- POJ--3468(线段树,区间修改,模板)
- 模板(线段树 + 树状数组 + 区间修改 + 区间查询)eg: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-线段数区间更新
- POJ 3468 A Simple Problem with Integers (树状数组) (区间修改+区间查询)
- poj 3468 区间修改查询 解题报告
- POJ 3468 A Simple Problem with Integers (线段树区间修改查询)
- POJ 3468 A Simple Problem with Integers (线段树区间修改)
- poj 3468:zkw树区间修改
- poj 3468(线段树区间修改合并)