데이터 구조 & 알고리즘 학습 노트: 선분 트 리
29116 단어 선분 수알고리즘 학습 노트
#define lson rt<<1, left, m
#define rson rt<<1|1, m + 1, right
const int maxn = 1e5+5;
using namespace std;
struct Node
{
int value;
int left,right;
int mid()
{
return (left + right) >> 1;
}
}node[maxn<<2];
int lindex[maxn];//
void PushUp(int rt)
{
node[rt].value = node[rt<<1].value + node[rt<<1|1].value;
//node[rt].value = max(node[rt<<1].value, node[rt<<1|1].value);
}
void BuildTree(int rt, int left, int right)
{
node[rt].left = left;
node[rt].right = right;
node[rt].value = 0;
if(left == right)
{
scanf("%d",&node[rt].value);
lindex[left] = rt;
return ;
}
int m = node[rt].mid();
BuildTree(lson);
BuildTree(rson);
PushUp(rt);
}
void Update(int rt)
{
if(rt == 1)return ;
int f = rt >> 1;
int a = node[f<<1].value;
int b = node[f<<1|1].value;
node[f].value = a + b;//
//node[f].value = max(a,b);//
Update(f);
}
int ans;
void Query(int rt, int left, int right)
{
if(node[rt].left == left && node[rt].right == right)
{
ans += node[rt].value;//
//ans = max(ans, node[rt].value);//
return ;
}
int m = node[rt].mid();
if(right <= m) Query(rt<<1, left, right);
else if(left > m) Query(rt<<1|1, left, right);
else{
Query(lson);
Query(rson);
}
}
연습 문제 연습 HDU 1754 (전송 문) I Hate It Time Limit: 9000 / 3000 MS (Java / Others) Memory Limit: 32768 / 32768 K (Java / Others) Problem 많은 학교 에서 비교 하 는 습관 이 유행 하고 있다.선생님 들 은 모모 에서 모모 까지 점수 가 가장 높 은 것 이 얼마 인지 묻 는 것 을 좋아한다.이것 은 많은 학생 들 로 하여 금 매우 반감 을 가지 게 한다.네가 좋아 하 든 안 좋아 하 든 지금 네가 해 야 할 일 은 바로 선생님 의 요구 에 따라 프로그램 을 써 서 선생님 의 질문 을 모 의 하 는 것 이다.물론 선생님 은 어떤 학우 의 성적 을 갱신 해 야 할 때 가 있다.Input 이 문 제 는 여러 그룹 테스트 를 포함 하고 있 습 니 다. 파일 이 끝 날 때 까지 처리 하 십시오.각 테스트 의 첫 줄 에는 두 개의 정수 N 과 M (0 < N < = 20000, 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 로 변경 하 라 고 요구 했다.Output 은 매번 문의 작업 에 대해 한 줄 에서 최고 성적 을 출력 합 니 다.Sample Input 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 Sample Output 5 6 5 9
Hint Huge input,the C function scanf() will work better than cin
#include
#include
#define lson rt<<1, left, m
#define rson rt<<1|1, m + 1, right
const int maxn = 2e5+5;
using namespace std;
struct Node
{
int value;
int left,right;
int mid()
{
return (left + right) >> 1;
}
}node[maxn<<2];
int lindex[maxn];
void PushUp(int rt)
{
node[rt].value = max(node[rt<<1].value, node[rt<<1|1].value);
}
void BuildTree(int rt, int left, int right)
{
node[rt].left = left;
node[rt].right = right;
node[rt].value = 0;
if(left == right)
{
cin>>node[rt].value;
lindex[left] = rt;
return ;
}
int m = node[rt].mid();
BuildTree(lson);
BuildTree(rson);
PushUp(rt);
}
void Update(int rt)
{
if(rt == 1)return ;
int f = rt >> 1;
int a = node[f<<1].value;
int b = node[f<<1|1].value;
node[f].value = max(a,b);
Update(f);
}
int ans;
void Query(int rt, int left, int right)
{
if(node[rt].left == left && node[rt].right == right)
{
ans = max(ans, node[rt].value);
return ;
}
int m = node[rt].mid();
if(right <= m) Query(rt<<1, left, right);
else if(left > m) Query(rt<<1|1, left, right);
else{
Query(lson);
Query(rson);
}
}
int main()
{
ios::sync_with_stdio(false);
int n, m;
while(cin>>n>>m)
{
BuildTree(1, 1, n);
while(m--)
{
string s;
int a, b;
cin>>s>>a>>b;
if(s[0] == 'Q')
{
ans = 0;
Query(1, a, b);
cout<else
{
if(s[0] == 'U')
{
node[lindex[a]].value = b;
Update(lindex[a]);
}
}
}
}
return 0;
}
NYOJ 116 (전송 문) 병사 의 적 을 죽 이 는 시간 제한: 1000 ms | 메모리 제한: 65535 KB 난이도: 5 남장 군 수하 에 N 명의 병사 가 있 는데 각각 1 번 에서 N 번 으로 번 호 를 매 겼 다. 이 병사 들 의 적 을 죽 이 는 수 는 모두 알려 져 있다.
막노동 자 는 남 장군 수하 의 군사 입 니 다. 남 장군 은 항상 m 번 부터 n 번 까지 병사 의 총 살 적 수 를 알 고 싶 어 합 니 다. 막노동 자 를 도와 남 장군 에 게 대답 해 주세요.
남 장군 의 한 질문 이후 병사 i 는 또 적 q 명 을 죽 일 수 있 습 니 다. 이후 남 장군 이 다시 물 었 을 때 추가 적 인 적 수 를 고려 해 야 합 니 다.
입력 한 테스트 데이터 의 첫 줄 은 두 개의 정수 N, M 입 니 다. 그 중에서 N 은 병사 의 개 수 를 표시 합 니 다 (1 < N < 1000000). M 은 명령 의 개 수 를 표시 합 니 다.(1 < M < 100000) 다음 줄 은 N 개의 정수 이 고 ai 는 제 i 호 병사 의 적 을 죽 이 는 수 를 나타 낸다.(0 < = ai < = 100) 다음 M 줄 은 각각 하나의 명령 입 니 다. 이 명령 은 하나의 문자열 과 두 개의 정 수 를 포함 하고 있 습 니 다. 먼저 하나의 문자열 입 니 다. 문자열 QUERY 라면 남 장군 이 조회 작업 을 했 고 뒤의 두 개의 정수 m, n 은 조회 의 시작 과 끝 병사 번 호 를 표시 합 니 다.문자열 ADD 라면 뒤 를 따 르 는 두 정수 I, A (1 < = I < = N, 1 < = A < = 100) 는 제 I 병사 의 신규 살 적 수 를 A 로 표시 합 니 다.각 그룹의 출력 이 한 줄 을 차지 하 는 샘플 입력 5 6 1 2 3 4 5 QUERY 1 3 ADD 1 2 QUERY 1 3 ADD 2 3 QUERY 1 2 QUERY 1 5 샘플 출력 6 8 20
#include
#include
#define lson rt<<1, left, m
#define rson rt<<1|1, m + 1, right
const int maxn = 1e6+5;
using namespace std;
struct Node
{
int value;
int left,right;
int mid()
{
return (left + right) >> 1;
}
}node[maxn<<2];
int lindex[maxn];
void PushUp(int rt)
{
node[rt].value = node[rt<<1].value + node[rt<<1|1].value;
}
void BuildTree(int rt, int left, int right)
{
node[rt].left = left;
node[rt].right = right;
node[rt].value = 0;
if(left == right)
{
cin>>node[rt].value;
lindex[left] = rt;
return ;
}
int m = node[rt].mid();
BuildTree(lson);
BuildTree(rson);
PushUp(rt);
}
void Update(int rt)
{
if(rt == 1)return ;
int f = rt >> 1;
int a = node[f<<1].value;
int b = node[f<<1|1].value;
node[f].value = a + b;
Update(f);
}
int ans;
void Query(int rt, int left, int right)
{
if(node[rt].left == left && node[rt].right == right)
{
ans += node[rt].value;
return ;
}
int m = node[rt].mid();
if(right <= m) Query(rt<<1, left, right);
else if(left > m) Query(rt<<1|1, left, right);
else{
Query(lson);
Query(rson);
}
}
int main()
{
int n, m;
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
BuildTree(1, 1, n);
string s;
int a, b;
for(int i = 0; i < m; i++)
{
ans = 0;
string s;
cin>>s>>a>>b;
if(s[0] == 'Q'){
Query(1, a, b);
cout<else{
if(s[0] == 'A')
{
node[lindex[a]].value += b;
Update(lindex[a]);
}
}
}
}
return 0;
}
HDU 1166 (전송 문) 은 상기 제목 과 유사 하 다.
// 【a,b】 c
#define lson rt<<1, left, m
#define rson rt<<1|1, m + 1, right
#define maxn 100004
using namespace std;
struct Node{
int left, right;
int value;
int add;//lazy
int mid()
{
return (left + right) >> 1;
}
}node[maxn<<2];
void PushUp(int rt)
{
node[rt].value = node[rt<<1].value + node[rt<<1|1].value;
}
void BuildTree(int rt, int left, int right)
{
node[rt].left = left;
node[rt].right = right;
node[rt].add = 0;
if(left == right)
{
scanf("%d",&node[rt].value);
return ;
}
int m = node[rt].mid();
BuildTree(lson);
BuildTree(rson);
PushUp(rt);
}
void PushDown(int rt, int len)// lazy
{//len
if(node[rt].add)
{
node[rt<<1].add += node[rt].add;
node[rt<<1|1].add += node[rt].add;
node[rt<<1].value += node[rt].add * (len - (len >> 1));//len - (len >> 1)
node[rt<<1|1].value += node[rt].add * (len >> 1);//len>>1
node[rt].add = 0;
}
}
void Update(int rt, int left, int right, int c)
{
if(node[rt].left == left && node[rt].right == right)
{
node[rt].value += (right - left + 1) * c;
node[rt].add += c;
return ;
}
PushDown(rt, node[rt].right - node[rt].left + 1);
int m = node[rt].mid();
if(right <= m)Update(rt<<1,left,right, c);
else if(left > m)Update(rt<<1|1,left,right, c);
else {
Update(lson, c);
Update(rson, c);
}
PushUp(rt);
}
void Query(int rt, int left, int right)
{
if(node[rt].left == left && node[rt].right == right)
{
ans += node[rt].value;
return ;
}
PushDown(rt, node[rt].right - node[rt].left + 1);
int m = node[rt].mid();
if(right <= m) Query(rt<<1,left,right);
else if(left > m) Query(rt<<1|1,left,right);
else{
Query(lson);
Query(rson);
}
}
연습 문제 Poj 3468 (전송 문) Integers 와 간단 한 문제 시간 제한: 5000 MS 메모리 제한: 131072 K 케이스 시간 제한: 2000 MS 설명
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 Hint
The sums may exceed the range of 32-bit integers.
#include
#include
#define lson rt<<1, left, m
#define rson rt<<1|1, m + 1, right
#define maxn 100004
using namespace std;
struct Node{
int left, right;
long long sum;
long long add;
int mid()
{
return (left + right) >> 1;
}
}node[maxn<<2];
void PushUp(int rt)
{
node[rt].sum = node[rt<<1].sum + node[rt<<1|1].sum;
}
void PushDown(int rt, int len)
{
if(node[rt].add)
{
node[rt<<1].add += node[rt].add;
node[rt<<1|1].add += node[rt].add;
node[rt<<1].sum += node[rt].add * (len - (len >> 1));//
node[rt<<1|1].sum += node[rt].add * (len >> 1);//
node[rt].add = 0;
}
}
void BuildTree(int rt, int left, int right)
{
node[rt].left = left;
node[rt].right = right;
node[rt].add = 0;
if(left == right)
{
scanf("%I64d",&node[rt].sum);
return ;
}
int m = node[rt].mid();
BuildTree(lson);
BuildTree(rson);
PushUp(rt);
}
void Update(int rt, int left, int right, long long c)
{
if(node[rt].left == left && node[rt].right == right)
{
node[rt].sum += (right - left + 1) * c;
node[rt].add += c;
return ;
}
PushDown(rt, node[rt].right - node[rt].left + 1);
int m = node[rt].mid();
if(right <= m)Update(rt<<1,left,right, c);
else if(left > m)Update(rt<<1|1,left,right, c);
else {
Update(lson, c);
Update(rson, c);
}
PushUp(rt);
}
long long ans;
void Query(int rt, int left, int right)
{
if(node[rt].left == left && node[rt].right == right)
{
ans += node[rt].sum;
return ;
}
PushDown(rt, node[rt].right - node[rt].left + 1);
int m = node[rt].mid();
if(right <= m) Query(rt<<1,left,right);
else if(left > m) Query(rt<<1|1,left,right);
else{
Query(lson);
Query(rson);
}
}
int main()
{
int n,q;
while(~scanf("%d%d",&n, &q))
{
BuildTree(1,1,n);
while(q--)
{
char s[3];
int a, b;
long long c;
scanf(" %s", s);
if(s[0] == 'Q')
{
ans = 0;
scanf("%d%d",&a,&b);
Query(1,a,b);
printf("%lld
",ans);
}
else
{
scanf("%d%d%I64d",&a,&b,&c);
Update(1,a,b,c);
}
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU - 1166 - 적병 포진 (나무형 수조 또는 선분 수)C 국 의 앙 숙 A 국 은 그동안 군사훈련 을 하고 있 었 기 때문에 C 국 간첩 두목 인 데 릭 과 그의 수하 인 티 디 는 또 바 빠 지기 시작 했다.A 국 가 는 해안선 을 따라 직선 으로 N 개 공병 캠프 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.