zoukankan      html  css  js  c++  java
  • NBUT校赛 J Alex’s Foolish Function(分块+延迟标记)

    Problem J: Alex’s Foolish Function

    Time Limit: 8 Sec  Memory Limit: 128 MB
    Submit: 18  Solved: 2

    Description

    Alex has an array F which size is n, initially each element’s value is zero. Now he wants to operate the array, he has 4 different functions:
    1) Function A(l, r):
    Add the elements between l to r (inclusive) where the i
    th add i - l + 1, for instance, if l is 4,
    r is 6 and the elements between 4 to 6 is 3 4 10, after this operation, these elements will become 4 6 13.
    2) Function B(l, r):
    Add the elements between l to r (inclusive) where the i
    th add r - i + 1, for instance, if l is 4,
    r is 6 and the elements between 4 to 6 is 3 4 10, after this operation, these elements will become 6 6 11.
    3) Function C(l, r, x):
    Set all the elements(between l to r) to x, for instance, if l is 4, r is 6 and the elements
    between 4 to 6 is 3 4 10, and x = 2, after this operation, these elements will become 2 2 2.
    4) Function S(l, r):
    Output F
    + Fl+1 + Fl+2 + ...+ Fr

     

    Input

    Input start with an integer T(1 <= T <= 5), denoting the number of test case.
    For each test case, first line contains n, m (1 <= n <= 200000, 1 <= m <= 100000), denoting the array’size and the number of operations.
    Next m lines, each line contains an operation, formatting as
    A l r
    B l r
    C l r x
    S l r 

     

    Output

    For each S Function operations, output the sum. 

     

    Sample Input

    1
    5 4
    A 1 3
    B 2 5
    C 1 1 2
    S 1 5

    Sample Output

    17

    正规做法是线段树维护区间的左加、右加或者覆盖信息,然而想用分块写一写。

    对于A操作,每一个块维护起始的加数,以及A操作的次数,

    对于B操作,每一个块维护末尾的加数,以及B操作的次数,

    对于C操作,每一个块维护准备覆盖的值val。

    显然对于A操作和B操作维护的信息,是满足区间加法的,即[1,4]A操作一次,[2,4]A操作一次,比如当前块是[2,4],记为Bx,那么我们可以记录起始的加数:(2-1+1)+(2-2+1)=3,A操作次数为2,即arr[2]+=3,arr[3]+=(3+2),arr[4]+=(3+2+2),然后我们可以发现这是一个等差数列,可以用公式快速得到有延迟标记A操作的区间和,即$(Bx.lazy_A+(Bx.lazy_A+Bx.len-1))*Bx.len/2+Bx.sum$,然后B操作也同理,最后加上本身的$Bx.sum$即可(这里要注意AB操作不能重复加Bx.sum);B操作同理;C操作的话由于是覆盖那么在更新的时候把更新到的块的$lazy_c$更新,并把$lazy_A$与$lazy_B$取消掉即可,由于可能$lazy_c$为0,初始值应设为一个不太可能用到的数,比如$-INF$。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define fin(name) freopen(name,"r",stdin)
    #define fout(name) freopen(name,"w",stdout)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 200010;
    const int M = 450;
    struct Block
    {
        int l, r;
        LL lazy1, lazy2, lazy3, sum;
        LL c1, c2;
    
        inline int len()
        {
            return r - l + 1;
        }
    };
    Block B[M];
    LL arr[N];
    int belong[N], unit, bcnt;
    int n, m;
    
    void init()
    {
        int i;
        unit = sqrt(n);
        bcnt = n / unit;
        if (n % unit)
            ++bcnt;
        for (i = 1; i <= bcnt; ++i)
        {
            B[i].l = (i - 1) * unit + 1;
            B[i].r = i * unit;
            B[i].sum = 0LL;
            B[i].lazy1 = 0LL;
            B[i].lazy2 = 0LL;
            B[i].lazy3 = -INF;
            B[i].c1 = B[i].c2 = 0LL;
        }
        B[bcnt].r = n;
        for (i = 1; i <= n; ++i)
        {
            arr[i] = 0LL;
            belong[i] = (i - 1) / unit + 1;
        }
    }
    void pushdown(int bx)
    {
        if (B[bx].lazy3 != -INF)
        {
            for (int i = B[bx].l; i <= B[bx].r; ++i)
                arr[i] = B[bx].lazy3;
            B[bx].lazy3 = -INF;
        }
        if (B[bx].lazy1)
        {
            for (int i = B[bx].l; i <= B[bx].r; ++i)
            {
                arr[i] += + B[bx].lazy1;
                B[bx].lazy1 += B[bx].c1;
            }
            B[bx].lazy1 = 0LL;
            B[bx].c1 = 0LL;
        }
        if (B[bx].lazy2)
        {
            for (int i = B[bx].r; i >= B[bx].l; --i)
            {
                arr[i] += + B[bx].lazy2;
                B[bx].lazy2 += B[bx].c2;
            }
            B[bx].lazy2 = 0LL;
            B[bx].c2 = 0LL;
        }
        B[bx].sum = 0LL;
        for (int i = B[bx].l; i <= B[bx].r; ++i)
            B[bx].sum += arr[i];
    }
    void update(int l, int r, int ops, LL val = 0LL)
    {
        int bl = belong[l], br = belong[r];
        int i;
        if (bl == br)
        {
            pushdown(bl);
            if (ops == 1)
            {
                for (i = l; i <= r; ++i)
                {
                    B[bl].sum -= arr[i];
                    arr[i] = arr[i] + (LL)(i - l + 1LL);
                    B[bl].sum += arr[i];
                }
            }
            else if (ops == 2)
            {
                for (i = r; i >= l; --i)
                {
                    B[bl].sum -= arr[i];
                    arr[i] = arr[i] + (LL)(r - i + 1LL);
                    B[bl].sum += arr[i];
                }
            }
            else if (ops == 3)
            {
                for (i = l; i <= r; ++i)
                {
                    B[bl].sum -= arr[i];
                    arr[i] = val;
                    B[bl].sum += arr[i];
                }
            }
        }
        else
        {
            //left
            pushdown(bl);
            if (ops == 1)
            {
                for (i = l; i <= B[bl].r; ++i)
                {
                    B[bl].sum -= arr[i];
                    arr[i] = arr[i] + (LL)(i - l + 1LL);
                    B[bl].sum += arr[i];
                }
            }
            else if (ops == 2)
            {
                for (i = B[bl].r; i >= l; --i)
                {
                    B[bl].sum -= arr[i];
                    arr[i] = arr[i] + (LL)(r - i + 1LL);
                    B[bl].sum += arr[i];
                }
            }
            else if (ops == 3)
            {
                for (i = l; i <= B[bl].r; ++i)
                {
                    B[bl].sum -= arr[i];
                    arr[i] = val;
                    B[bl].sum += arr[i];
                }
            }
            //right
            pushdown(br);
            if (ops == 1)
            {
                for (i = B[br].l; i <= r; ++i)
                {
                    B[br].sum -= arr[i];
                    arr[i] = arr[i] + (LL)(i - l + 1LL);
                    B[br].sum += arr[i];
                }
            }
            else if (ops == 2)
            {
                for (i = r; i >= B[br].l; --i)
                {
                    B[br].sum -= arr[i];
                    arr[i] = arr[i] + (LL)(r - i + 1LL);
                    B[br].sum += arr[i];
                }
            }
            else if (ops == 3)
            {
                for (i = B[br].l; i <= r; ++i)
                {
                    B[br].sum -= arr[i];
                    arr[i] = val;
                    B[br].sum += arr[i];
                }
            }
            for (i = bl + 1; i < br; ++i)
            {
                if (ops == 3)
                {
                    B[i].lazy3 = val;
                    B[i].c1 = 0LL;
                    B[i].c2 = 0LL;
                    B[i].lazy1 = 0LL;
                    B[i].lazy2 = 0LL;
                }
                else if (ops == 2)
                {
                    B[i].lazy2 += (LL)(r - B[i].r + 1LL);
                    ++B[i].c2;
                }
                else if (ops == 1)
                {
                    B[i].lazy1 += (LL)(B[i].l - l + 1LL);
                    ++B[i].c1;
                }
            }
        }
    }
    LL query(int l, int r)
    {
        int bl = belong[l], br = belong[r], i;
        LL sum = 0LL;
        if (bl == br)
        {
            pushdown(bl);
            for (i = l; i <= r; ++i)
                sum += arr[i];
            return sum;
        }
        else
        {
            pushdown(bl);
            pushdown(br);
            for (i = l; i <= B[bl].r; ++i)
                sum += arr[i];
            for (i = B[br].l; i <= r; ++i)
                sum += arr[i];
            for (i = bl + 1; i < br; ++i)
            {
                if (B[i].lazy3 != -INF)
                    sum += (LL)B[i].len() * B[i].lazy3;
                if (B[i].lazy1)
                    sum += (B[i].lazy1 + B[i].lazy1 + (LL)(B[i].len() - 1LL) * B[i].c1) * (LL)B[i].len() / 2LL;
                if (B[i].lazy2)
                    sum += (B[i].lazy2 + B[i].lazy2 + (LL)(B[i].len() - 1LL) * B[i].c2) * (LL)B[i].len() / 2LL;
                if (B[i].lazy3 == -INF)
                    sum += B[i].sum;
            }
            return sum;
        }
    }
    int main(void)
    {
        // fin("test0.in");
        // fout("data_wa.txt");
        int tcase, l, r, v;
        char ops[4];
        scanf("%d", &tcase);
        while (tcase--)
        {
            scanf("%d%d", &n, &m);
            init();
            while (m--)
            {
                scanf("%s", ops);
                if (ops[0] == 'A')
                {
                    scanf("%d%d", &l, &r);
                    update(l, r, 1);
                }
                else if (ops[0] == 'B')
                {
                    scanf("%d%d", &l, &r);
                    update(l, r, 2);
                }
                else if (ops[0] == 'C')
                {
                    scanf("%d%d%d", &l, &r, &v);
                    update(l, r, 3, (LL)v);
                }
                else
                {
                    scanf("%d%d", &l, &r);
                    printf("%lld
    ", query(l, r));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Unity3D系列教程--使用免费工具在Unity3D中开发2D游戏 第一节
    第十三周项目2:形状类族中的纯虚函数
    js中的null和undefined
    javaScript Windows相关
    Array和ArrayList的异同点
    汉语-词语-人才:T型人才
    图书-计算机-软件编程:《程序员的自我需要》
    智力-智力测试-门萨:百科
    智力开发-早教:七田真
    经济-AMA:百科
  • 原文地址:https://www.cnblogs.com/Blackops/p/7223649.html
Copyright © 2011-2022 走看看