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

HDU 4578 线段树区间更新(确定区间操作的优先级)

时间:2014-05-09 01:08:38      阅读:432      评论:0      收藏:0      [点我收藏+]

标签:线段树

HDU 4578

线段树区间更新


操作有:

区间所有数add(c)

区间所有数mul(c)

区间所有数set(c)

查询有:

区间所有数的p次方和(p>= 1 && p <= 3)


关键是区间更新的三种操作的优先级的确定清楚set>mul>add

关键是:down和update中对区间的更新操作是一回事,可以写成函数方便编程


//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)

typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int maxn = 100010;
const int MOD = 10007;

#define ll rt << 1
#define rr rt << 1 | 1
int q[3][maxn << 2];
int setval[maxn << 2], add[maxn << 2], mul[maxn << 2];

void up(int rt)
{
    for (int i = 0; i < 3; i++)
        q[i][rt] = (q[i][ll] + q[i][rr]) % MOD;
}
void down_setval(int rt, int c, int len)
{
    int a[4]; a[1] = c;
    for (int i = 2; i <= 3; i++)
        a[i] = a[i - 1] * a[1] % MOD;
    for (int i = 0; i < 3; i++)
        q[i][rt] = a[i + 1] * len % MOD;
    setval[rt] = c;
    add[rt] = 0;///
    mul[rt] = 1;///
}
void down_addval(int rt, int c, int len)
{
    int a[4]; a[1] = c;
    for (int i = 2; i <= 3; i++)
        a[i] = a[i - 1] * a[1] % MOD;

    q[2][rt] = q[2][rt] % MOD + a[3] * len % MOD + 3 * a[2] % MOD * q[0][rt] % MOD + 3 * a[1] % MOD * q[1][rt] % MOD;
    q[1][rt] = q[1][rt] % MOD + a[2] * len % MOD + 2 * a[1] % MOD * q[0][rt] % MOD;
    q[0][rt] = q[0][rt] + a[1] * len % MOD;
    for (int i = 0; i < 3; i++)
        q[i][rt] %= MOD;
    add[rt] = (add[rt] + c) % MOD;
}
void down_mulval(int rt, int c, int len)
{
    int a[4]; a[1] = c;
    for (int i = 2; i <= 3; i++)
        a[i] = a[i - 1] * a[1] % MOD;
    for (int i = 0; i < 3; i++)
        q[i][rt] = (q[i][rt] * a[i + 1]) % MOD;
    mul[rt] = (mul[rt] * c) % MOD;
    add[rt] = (add[rt] * c) % MOD;
}
void down(int rt, int l, int r)
{
    int m = (l + r) >> 1;
    if (setval[rt] != -1)///!!!
    {
        down_setval(ll, setval[rt], m - l + 1);
        down_setval(rr, setval[rt], r - m);
        setval[rt] = -1;///!!!
//        return ;
    }
    if (mul[rt] != 1)
    {
        down_mulval(ll, mul[rt], m - l + 1);
        down_mulval(rr, mul[rt], r - m);
        mul[rt] = 1;
    }
    if (add[rt] != 0)
    {
        down_addval(ll, add[rt], m - l + 1);
        down_addval(rr, add[rt], r - m);
        add[rt] = 0;
    }
}
void update(int L, int R, int qx, int c, int l, int r, int rt)
{
    if (L <= l && r <= R)
    {
        if (qx == 3) down_setval(rt, c, r - l + 1);
        else if (qx == 1) down_addval(rt, c, r - l + 1);
        else down_mulval(rt, c, r - l + 1);
        return ;
    }
    int m = (l + r) >> 1;
    down(rt, l, r);
    if (L <= m) update(L, R, qx, c, l, m, ll);
    if (m < R) update(L, R, qx, c, m +1, r, rr);
    up(rt);
}
int query(int L, int R, int c,int l, int r, int rt)
{
    if (L <= l && r <= R)
        return q[c - 1][rt];
    int m = (l + r) >> 1;
    down(rt, l, r);
    int ret = 0;
    if (L <= m) ret = (ret + query(L, R, c, l, m, ll)) % MOD;
    if (m < R) ret = (ret + query(L, R, c, m + 1, r, rr)) % MOD;
    return ret;
}
int main ()
{
    int n, m;
    while (scanf("%d%d", &n, &m) == 2)
    {
        if (n + m == 0) break;
        CLR(q, 0);
        CLR(setval, -1);///!!!
        CLR(add, 0);
        for (int i = 0; i < maxn * 4; i++) mul[i] = 1;
        //
        while (m--)
        {
            int qx, x, y, c;
            RI(qx);
            RIII(x, y, c);
            if (qx <= 3) update(x, y, qx, c, 1, n, 1);
            else printf("%d\n", query(x, y, c, 1, n, 1));
        }
    }
    return 0;
}

另一种:

//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)

typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int maxn = 100010;
const int MOD = 10007;

#define ll rt << 1
#define rr rt << 1 | 1
int q[3][maxn << 2];
int setval[maxn << 2], add[maxn << 2], mul[maxn << 2];

void up(int rt)
{
    for (int i = 0; i < 3; i++)
        q[i][rt] = (q[i][ll] + q[i][rr]) % MOD;
}
void down_setval(int rt, int c, int len)
{
    int a[4];
    a[1] = c;
    for (int i = 2; i <= 3; i++)
        a[i] = a[i - 1] * a[1] % MOD;
    for (int i = 0; i < 3; i++)
        q[i][rt] = a[i + 1] * len % MOD;

    setval[rt] = c;
    add[rt] = 0;///
    mul[rt] = 1;///
}
void down_nosetval(int rt, int a, int b, int len)
{
    int ta[4], tb[4];
    ta[1] = a, tb[1] = b;
    for (int i = 2; i <= 3; i++)
        ta[i] = ta[i - 1] * ta[1] % MOD, tb[i] = tb[i - 1] * tb[1] % MOD;
    q[2][rt] = ta[3] * q[2][rt] % MOD + tb[3] * len % MOD + 3 * ta[2] % MOD * tb[1] % MOD * q[1][rt] % MOD + 3 * ta[1] % MOD * tb[2] % MOD * q[0][rt] % MOD;
    q[2][rt] %= MOD;
    q[1][rt] = ta[2] * q[1][rt] % MOD + tb[2] * len % MOD + 2 * ta[1] % MOD * tb[1] % MOD * q[0][rt] % MOD;
    q[1][rt] %= MOD;
    q[0][rt] = ta[1] * q[0][rt] % MOD + tb[1] * len % MOD;
    q[0][rt] %= MOD;
    if (setval[rt] != -1)///!!!
    {
        setval[rt] = setval[rt] * a + b;
        setval[rt] %= MOD;
    }
    else
    {
        mul[rt] = mul[rt] * a;
        add[rt] = add[rt] * a + b;
        mul[rt] %= MOD;
        add[rt] %= MOD;
    }
}
void down(int rt, int l, int r)
{
    int m = (l + r) >> 1;
    if (setval[rt] != -1)///!!!
    {
        down_setval(ll, setval[rt], m - l + 1);
        down_setval(rr, setval[rt], r - m);
        setval[rt] = -1;///!!!

        add[rt] = 0;
        mul[rt] = 1;
    }
    else
    {
        int a = mul[rt], b = add[rt];
        down_nosetval(ll, a, b, m - l + 1);
        down_nosetval(rr, a, b, r - m);
        add[rt] = 0;
        mul[rt] = 1;

    }
}
void update(int L, int R, int qx, int c, int l, int r, int rt)
{
    if (L <= l && r <= R)
    {
        if (qx == 3)
            down_setval(rt, c, r - l + 1);
        else
        {
            int a = 1, b = 0;
            if (qx == 1) b = c;
            else a = c;
            down_nosetval(rt, a, b, r - l + 1);
        }
        return ;
    }
    int m = (l + r) >> 1;
    down(rt, l, r);
    if (L <= m) update(L, R, qx, c, l, m, ll);
    if (m < R) update(L, R, qx, c, m +1, r, rr);
    up(rt);
}
int query(int L, int R, int c,int l, int r, int rt)
{
    if (L <= l && r <= R)
        return q[c - 1][rt];
    int m = (l + r) >> 1;
    down(rt, l, r);
    int ret = 0;
    if (L <= m) ret = (ret + query(L, R, c, l, m, ll)) % MOD;
    if (m < R) ret = (ret + query(L, R, c, m + 1, r, rr)) % MOD;
    return ret;
}
int main ()
{
    int n, m;
    while (cin >> n >> m)
    {
        if (n + m == 0) break;
        CLR(q, 0);
        CLR(setval, -1);///!!!
        CLR(add, 0);
        REP(i, maxn << 2) mul[i] = 1;
        //
        while (m--)
        {
            int qx, x, y, c;
            RI(qx);
            RIII(x, y, c);
            if (qx <= 3) update(x, y, qx, c, 1, n, 1);
            else cout << query(x, y, c, 1, n, 1) % MOD << endl;
        }
    }
    return 0;
}



HDU 4578 线段树区间更新(确定区间操作的优先级),布布扣,bubuko.com

HDU 4578 线段树区间更新(确定区间操作的优先级)

标签:线段树

原文地址:http://blog.csdn.net/guognib/article/details/25324025

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