세그먼트 트리 템플릿이 [반 무단 전재 ..

재판 문

에서 설명 : https://www.luogu.org/blog/running-coder/solution-p3373
주제로 :( 다음은 본문에 SGT 구조했다)

템플릿이 질문에 대하여이 범위 곱하기 때문에 함수 (간격 승산), 기본 템플릿 (승산 지연 기록 마크)의 배열을 열어 작성할 필요 첨가하고, 지연하도록 기능의 분산을 표시한다 일부 수정.

변수 정의 :
] SUM [: 간격의 합에 대응하는 요소 세그먼트 트리 노드;

ADDV []의 값에 대응하는 세그먼트 트리 노드 존의 모든 요소는 모든 초기 값 0으로 설정 (지연 마크)를 첨가하는 단계;

mulv []의 값에 대응하는 세그먼트 트리 노드 존의 모든 요소 (지연 마크)가 초기 값 1의 모든 세트를 승산한다.

공정 설명 :
성과 (빌드) :
템플릿과 함께. . .

게으른 마크 지방 분권 (Push_down가)
의 원리를 설명 :

낮은 우선 순위의 첨가 이후, 세그먼트에 가산 연산을 수행하는 단계, 동작은 승산에 영향을주지 않는 경우 1.는 직접 첨가 될 수있다;

2. 동작을 추가하는 영향을하기 전에,이 합이 곱 위해 단지 요구와 승산 mulv도 ADDV 승산 요구되고, 높은 승산 우선 순위의 범위에서 곱셈 연산을 수행 할 때;

상기 이유로 3, 곱셈 연산자 가산기를 재 계산해야한다.

구현의 세부 사항 :

합계 1 서브 트리가 mulv는 ADDV MuLV 값은 현재 노드의 값으로 곱 하였다;

2. 1로 설정 즉, 현재 노드 mulv 감소의 값;

3. 서브 트리의 ADDV ADDV 값 더하기 현재 노드의 값;

제 합산 값 더하기 하위 트리 (서브 트리의 요소 수를 포함 * 현재 노드의 ADDV 값);

5. 환원 전류 값 ADDV 노드, 즉 제로로 설정.

특별 참고 사항 :

1. 현재 노드가이 기능을 위임 행하지 않고, 빈 플래그가 지연되는 경우, 사용하기 전에 결정. 그것은 실행하지만, 시간 낭비에 영향을주지 않습니다 만,

대신 함수이 함수의 외부에 결정에 2. 시간을 절약하려고합니다.

간격 플러스 (모두 추가) :
템플릿과 함께. . .

간격 (Mulall) 저자 :
현재 노드가 완전히 업데이트 간격 내에 함유되는 경우, 현재 노드는 직접 (분산 함수를 참조하여 설명) 값 mulv, ADDV, 합계 수정된다;

그렇지 않으면, 간격을 높이기 위해 유사한 작업을 수행합니다.

간격 질의 (쿼리) :
템플릿과 함께. . .

팁 : 모듈을 잊지 마세요. . .

개인 코드

luoguP3373

#include<cstdio>
using namespace std;
#define MAX 100000+99
#define ll long long

int n,m,p;
ll sumv[MAX<<2], addv[MAX<<2], mulv[MAX<<2];
ll a[MAX];

void push_up(int o) { sumv[o] = (sumv[o<<1] + sumv[o<<1|1] ) % p;}
void build(int o, int l, int r) {
    addv[o] = 0; mulv[o] = 1;
    if(l == r) { sumv[o] = a[l]; return;}
    int mid = (l+r)>>1;
    build(o<<1, l, mid);
    build(o<<1|1, mid+1, r);
    push_up(o);
}

//void pushtag()这里的pushtag不一样,我就不写了
void push_down(int o, int l, int r) {
    if(mulv[o] != 1) {//先传mul 
        mulv[o<<1] = (mulv[o<<1] * mulv[o]) % p;
        mulv[o<<1|1] = (mulv[o<<1|1] * mulv[o]) % p;
        addv[o<<1] = (addv[o<<1] * mulv[o]) % p;
        addv[o<<1|1] = (addv[o<<1|1] * mulv[o]) % p;
        sumv[o<<1] = (sumv[o<<1] * mulv[o]) % p;
        sumv[o<<1|1] = (sumv[o<<1|1] * mulv[o]) % p;
        mulv[o] = 1;
    }
    if(addv[o]) {
        addv[o<<1] = (addv[o<<1] + addv[o]) % p;
        addv[o<<1|1] = (addv[o<<1|1] + addv[o]) % p;
        int mid = (l + r) >> 1;
        sumv[o<<1] = (sumv[o<<1] + addv[o]*(mid-l+1) ) % p;
        sumv[o<<1|1] = (sumv[o<<1|1] + addv[o]*(r-mid) ) % p ;
        addv[o] = 0;
    }
} 

void optadd(int o, int l, int r, int ql, int qr, int v) {
    if(ql <= l && r <= qr) {
        addv[o] = (ll)(addv[o] + v) % p;
        sumv[o] = (ll)(sumv[o] + v*(r-l+1) ) % p;
        return ;
    }
    push_down(o,l,r);
    int mid = (l + r) >> 1;
    if(ql <= mid) optadd(o<<1, l, mid, ql, qr, v);
    if(mid < qr) optadd(o<<1|1, mid+1, r, ql, qr, v);
    push_up(o);
}

void optmul(int o, int l, int r, int ql, int qr, int v) {
    if(ql <= l && r <= qr) {
        mulv[o] = (ll)(mulv[o] * v) % p;
        addv[o] = (ll)(addv[o] * v) % p;
        sumv[o] = (ll)(sumv[o] * v) % p;
        return ;
    }
    push_down(o,l,r);
    int mid = (l + r) >> 1;
    if(ql <= mid) optmul(o<<1, l, mid, ql, qr, v);
    if(mid < qr) optmul(o<<1|1, mid+1, r, ql, qr, v);
    push_up(o);
}

ll query(int o, int l, int r, int ql, int qr) {
    if(ql <= l && r <= qr) return (ll)sumv[o]%p;
    push_down(o,l,r);
    ll ans = 0;
    int mid = (l + r) >> 1;
    if(ql <= mid) ans = (ans + query(o<<1, l, mid, ql, qr) ) % p;
    if(mid < qr) ans = (ans + query(o<<1|1, mid+1, r, ql, qr) ) % p;
    return ans%p;
}

int main() {
    scanf("%d%d%d",&n,&m,&p);
    for(int i = 1; i <= n; i++) scanf("%lld",&a[i]);
    build(1,1,n);
    int tmp, l, r, v;
    for(int i = 1; i <= m; i++) {
        scanf("%d", &tmp);
        if(tmp == 1) { scanf("%d%d%d", &l, &r, &v); optmul(1, 1, n, l, r, v); }
        else if(tmp == 2) { scanf("%d%d%d", &l, &r, &v); optadd(1, 1, n, l, r, v); }
        else if(tmp == 3) { scanf("%d%d", &l, &r); printf("%lld\n", query(1, 1, n, l, r)); }
    }
    return 0;
}
/*
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
*/

추천

출처www.cnblogs.com/tyner/p/11237282.html