선분 트 리 기초 작업 - 단점 또는 구간 업데이트 + 조회

문제 개술: 먼저 하나의 숫자 n 을 입력 하면 한 반 에 n 명 이 있다 는 것 을 나타 낸다. 처음에 모든 사람 이 손 에 사탕 이 하나 있 었 다. 그 다음 에 하나의 수 m 를 입력 하고 m 번 조작 을 한다. 매번 에 a, b, c 를 조작 할 때마다 첫 번 째 사람 부터 b 번 째 사람 까지 모든 사람 이 c 개의 사탕 을 재배 치 하여 마지막 반 모든 사람의 총 사탕 수 를 구한다.
입력 예시:                                    대응 하 는 출력:
1                                                     24
10
2
1 5 2
5 9 3
구간 업데이트 (직접 업데이트 할 수 없 음) 게 으 름 표 시 를 사용 해 야 하 는 이유:
한 구간 의 값 을 수정 하 는 것 은 이 구간 과 관련 된 모든 하위 노드 와 부모 노드 에 영향 을 줄 수 있 습 니 다. 부모 노드 를 바 꾸 는 것 은 쉬 운 일이 고 모든 하위 노드 를 바 꾸 는 것 은 너무 시간 이 걸 리 기 때문에 하나의 배열 로 어떤 노드 의 하위 노드 점 수 를 표시 하려 면 바 뀌 어야 합 니까? 두 번 째 로 이 노드 를 사용 할 때 하위 노드 를 바 꾸 어야 합 니까?
코드 에 주석 이 있 습 니 다.
#include
#include
int n, tre[444444], temp[444444];
void Readin(int l, int r, int x);
void Update(int l, int r, int x, int a, int b, int val);
void lazy(int l, int r, int x);
int main(void)
{
	int T, m, i, a, b, val;
	scanf("%d", &T);
	while(T--)
	{
		memset(temp, 0, sizeof(temp));
		scanf("%d%d", &n, &m);
		Readin(1, n, 1);
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d", &a, &b, &val);
			Update(1, n, 1, a, b, val);
		}
		printf("%d
", tre[1]); } return 0; } void Readin(int l, int r, int x) /* , */ { int m; if(l==r) { tre[x] = 1; return; } m = (l+r)/2; Readin(l, m, x*2); Readin(m+1, r, x*2+1); tre[x] = tre[x*2]+tre[x*2+1]; } void Update(int l, int r, int x, int a, int b, int val) /* */ { int m; if(l>=a && r<=b) /* a b , */ { tre[x] = (r-l+1)*val; if(l!=r) temp[x] = val; /*temp[x] val*/ return; /*temp[x]==0 */ } if(temp[x]!=0) lazy(l, r, x); /* */ m = (l+r)/2; if(a<=m) Update(l, m, x*2, a, b, val); if(b>=m+1) Update(m+1, r, x*2+1, a, b, val); tre[x] = tre[x*2]+tre[x*2+1]; } void lazy(int l, int r, int x) /* */ { int m; if(l!=r) temp[x*2] = temp[x*2+1] = temp[x]; /* ( , )*/ m = (l+r)/2; tre[x*2] = (m-l+1)*temp[x]; tre[x*2+1] = (r-m)*temp[x]; temp[x] = 0; /* ,temp[x] 0*/ }

좋은 웹페이지 즐겨찾기