码迷,mamicode.com
首页 > 其他好文 > 详细

HDU - 4578 Transformation(线段树区间修改)

时间:2018-09-02 18:43:23      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:math.h   const   立方和   int   线段   math   stdout   span   使用   

https://cn.vjudge.net/problem/HDU-4578

题意

4种操作,区间加,区间乘,区间变为一个数,求区间的和、平方和以及立方和。

分析

明显线段树,不过很麻烦。。看kuangbin大神的代码打的

用sum1,sum2,sum3分别代表和、平方和、立方和。

懒惰标记使用三个变量:

lazy1:是加的数

lazy2:是乘的倍数

lazy3:是赋值为一个常数,为0表示没有。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MOD = 10007;
const int MAXN = 100010;
struct Node {
    int l,r;
    int sum1,sum2,sum3;
    int lazy1,lazy2,lazy3;
} segTree[MAXN*3];
void build(int i,int l,int r) {
    segTree[i].l = l;
    segTree[i].r = r;
    segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = 0;
    segTree[i].lazy1 = segTree[i].lazy3 = 0;
    segTree[i].lazy2 = 1;
    int mid = (l+r)/2;
    if(l == r)return;
    build(i<<1,l,mid);
    build((i<<1)|1,mid+1,r);
}
void push_up(int i) {
    if(segTree[i].l == segTree[i].r)
        return;
    segTree[i].sum1 = (segTree[i<<1].sum1 + segTree[(i<<1)|1].sum1)%MOD;
    segTree[i].sum2 = (segTree[i<<1].sum2 + segTree[(i<<1)|1].sum2)%MOD;
    segTree[i].sum3 = (segTree[i<<1].sum3 + segTree[(i<<1)|1].sum3)%MOD;

}

void push_down(int i) {
    if(segTree[i].l == segTree[i].r) return;
    if(segTree[i].lazy3 != 0) {
        segTree[i<<1].lazy3 = segTree[(i<<1)|1].lazy3 = segTree[i].lazy3;
        segTree[i<<1].lazy1 = segTree[(i<<1)|1].lazy1 = 0;
        segTree[i<<1].lazy2 = segTree[(i<<1)|1].lazy2 = 1;
        segTree[i<<1].sum1 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD;
        segTree[i<<1].sum2 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD;
        segTree[i<<1].sum3 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD;
        segTree[(i<<1)|1].sum1 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD;
        segTree[(i<<1)|1].sum2 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD;
        segTree[(i<<1)|1].sum3 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD;
        segTree[i].lazy3 = 0;
    }
    if(segTree[i].lazy1 != 0 || segTree[i].lazy2 != 1) {
        segTree[i<<1].lazy1 = ( segTree[i].lazy2*segTree[i<<1].lazy1%MOD + segTree[i].lazy1 )%MOD;
        segTree[i<<1].lazy2 = segTree[i<<1].lazy2*segTree[i].lazy2%MOD;
        int sum1,sum2,sum3;
        sum1 = (segTree[i<<1].sum1*segTree[i].lazy2%MOD + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD)%MOD;
        sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<1].sum2 % MOD + 2*segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<1].sum1%MOD + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
        sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<1].sum3 % MOD;
        sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1].sum2) % MOD;
        sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1].sum1) % MOD;
        sum3 = (sum3 + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
        segTree[i<<1].sum1 = sum1;
        segTree[i<<1].sum2 = sum2;
        segTree[i<<1].sum3 = sum3;
        segTree[i<<1|1].lazy1 = ( segTree[i].lazy2*segTree[i<<1|1].lazy1%MOD + segTree[i].lazy1 )%MOD;
        segTree[i<<1|1].lazy2 = segTree[i<<1|1].lazy2*segTree[i].lazy2%MOD;

        sum1 = (segTree[i<<1|1].sum1*segTree[i].lazy2%MOD + (segTree[i<<1|1].r - segTree[i<<1|1].l + 1)*segTree[i].lazy1%MOD)%MOD;
        sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<1|1].sum2 % MOD + 2*segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<1|1].sum1%MOD + (segTree[i<<1|1].r - segTree[i<<1|1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
        sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<1|1].sum3 % MOD;
        sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1|1].sum2) % MOD;
        sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1|1].sum1) % MOD;
        sum3 = (sum3 + (segTree[i<<1|1].r - segTree[i<<1|1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
        segTree[i<<1|1].sum1 = sum1;
        segTree[i<<1|1].sum2 = sum2;
        segTree[i<<1|1].sum3 = sum3;
        segTree[i].lazy1 = 0;
        segTree[i].lazy2 = 1;

    }
}
void update(int i,int l,int r,int type,int c) {
    if(segTree[i].l >= l && segTree[i].r <= r) {
        c %= MOD;
        if(type == 1) {
            segTree[i].lazy1 += c;
            segTree[i].lazy1 %= MOD;
            segTree[i].sum3 = (segTree[i].sum3 + 3*segTree[i].sum2%MOD*c%MOD + 3*segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD*c%MOD)%MOD;
            segTree[i].sum2 = (segTree[i].sum2 + 2*segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD)%MOD;
            segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + 1)*c%MOD)%MOD;
        } else if(type == 2) {
            segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
            segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
            segTree[i].sum1 = segTree[i].sum1*c%MOD;
            segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
            segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
        } else {
            segTree[i].lazy1 = 0;
            segTree[i].lazy2 = 1;
            segTree[i].lazy3 = c%MOD;
            segTree[i].sum1 = c*(segTree[i].r - segTree[i].l + 1)%MOD;
            segTree[i].sum2 = c*(segTree[i].r - segTree[i].l + 1)%MOD*c%MOD;
            segTree[i].sum3 = c*(segTree[i].r - segTree[i].l + 1)%MOD*c%MOD*c%MOD;
        }
        return;
    }
    push_down(i);
    int mid = (segTree[i].l + segTree[i].r)/2;
    if(l <= mid)update(i<<1,l,r,type,c);
    if(r > mid)update((i<<1)|1,l,r,type,c);
    push_up(i);
}
int query(int i,int l,int r,int p) {
    if(segTree[i].l >= l && segTree[i].r <= r) {
        if(p == 1)return segTree[i].sum1;
        else if(p== 2)return segTree[i].sum2;
        else return segTree[i].sum3;
    }
    push_down(i);
    int mid = (segTree[i].l + segTree[i].r )/2;
    int sum=0;
    if(l <= mid) sum+=query(i<<1,l,r,p);
    if(r > mid) sum+=query((i<<1)|1,l,r,p);
    return sum%MOD;
}

int main() {
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,m;
    while(scanf("%d%d",&n,&m) == 2) {
        if(n == 0 && m == 0)break;
        build(1,1,n);
        int type,x,y,c;
        while(m--) {
            scanf("%d%d%d%d",&type,&x,&y,&c);
            if(type == 4)printf("%d\n",query(1,x,y,c));
            else update(1,x,y,type,c);
        }
    }
    return 0;
}

 

HDU - 4578 Transformation(线段树区间修改)

标签:math.h   const   立方和   int   线段   math   stdout   span   使用   

原文地址:https://www.cnblogs.com/fht-litost/p/9574492.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!