首页 > 代码库 > NBUT校赛 J Alex’s Foolish Function(分块+延迟标记)

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

15 4A 1 3B 2 5C 1 1 2S 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\n", query(l, r));            }        }    }    return 0;}

NBUT校赛 J Alex’s Foolish Function(分块+延迟标记)