Zoj 3813 Alternating Sum (line segment tree), zoj3813

Source: Internet
Author: User

Zoj 3813 Alternating Sum (line segment tree), zoj3813

Link: zoj 3813 Alternating Sum

Given a P, S is an infinite string that uses P as a loop and defines G (I, j). Now there are two operations:

  • 1 x d; change the position of x in P to d
  • 2 l r: query the sum of all G (I, j) values between l-r in S.

Solution: Modify the interval query points of the Line Segment tree.
According to the G (I, j) formula, you can export: each query l ~ The answer to the r interval is:

  • Odd Number: sl using len + sl + 2 then (len −2) + sl + 4 then (len −4) + then + sr using 1
  • Even number: sl then len + sl + 2 then (len − 2) + sl + 4 then (len − 4) + then + sr − 1 then 2
    Therefore, a line segment tree (Unified parity operation) is created for twice the P value. Because the P value is set to two times, the two locations must be modified.
    Each node maintains four values:
  • Sum [0]; sum of the numbers at the same position as the l parity in the interval
  • Sum [1]: sum of the numbers at different locations of the parity between the range and the l
  • Ans [0]: Query range l ~ Answer in r
  • Ans [1]: Query range l + 1 ~ The answer to r (Here r is relative, according to l's parity)

    During range merge, the merge operation is determined based on the length of the left child. When merging, you need to consider the coefficient change in the left child's answer calculation due to the length increase. You need to multiply the length of the range of the right child, after the common factor is extracted, the sum is maintained in advance.
    During query, if the interval is less than 2 P, you can directly Insert the data into the table. When the value is greater than 2 P, the entire segment difference must be divided into three segments for pre, mid, and suf processing, and then merged using the range merging method. Note that the mid value is 2 P n times, when the length of P is short, n will be very large, so we cannot traverse the computation. We need to push it into the sum of the arithmetic difference series, and pay attention to the multiplication of long.

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)+1)typedef long long ll;const int maxn = 200005;const ll mod = 1e9+7;struct Node {    int l, r;    ll sum[2], ans[2];}nd[maxn*4];int N, M;char str[maxn];void pushup(int u);Node query(int u, int x, int y);void modify (int u, int x, int v);void build_segTree(int u, int l, int r);inline ll cal(ll n) {    if (n&1)        return ((n-1) / 2 % mod) * (n % mod) % mod;    else        return (n / 2 % mod) * ((n-1) % mod) % mod;}void init () {    scanf("%s", str);    N = strlen(str);    M = 2 * N;    build_segTree(1, 1, M);}int solve (ll x, ll y) {    ll p = (x-1) / M, q = (y-1) / M;    if (p != q) {        int d = (x % 2) ^ 1;        ll n = (q - p - 1) % mod;        Node pre = query(1, (x-1) % M + 1, M);        Node mid = query(1, 1, M);        Node suf = query(1, 1, (y-1) % M + 1);        // pre;        ll ret = (pre.ans[0] + pre.sum[0] * (n * M % mod)) % mod;        ll s = (pre.sum[0] + mid.sum[d] * n) % mod;        // mid;        ret = (ret + mid.ans[d] * n) % mod;        //ret = (ret + (mid.sum[d] * (((n&1) ? ((n-1)/2)%mod*n : (n/2)%mod*(n-1))%mod)) * M)  % mod;        ret = (ret + (mid.sum[d] * cal(n) % mod) * M)  % mod;        // suf;        ret = (ret + s * (suf.r - suf.l + 1) + suf.ans[d]) % mod;        return ret;    } else        return query(1, (x-1) % M + 1, (y-1) % M + 1).ans[0];}int main () {    int cas, n, k;    ll x, y;    scanf("%d", &cas);    while (cas--) {        init();        scanf("%d", &n);        while (n--) {            scanf("%d%lld%lld", &k, &x, &y);            if (k == 1) {                modify(1, x, y);                modify(1, x + N, y);            } else                printf("%d\n", solve(x, y));        }    }    return 0;}void pushup (int u) {    int d = (nd[lson(u)].r - nd[lson(u)].l + 1) & 1;    int L = (nd[rson(u)].r - nd[rson(u)].l + 1) % mod;    for (int i = 0; i < 2; i++) {        nd[u].sum[i] = (nd[lson(u)].sum[i] + nd[rson(u)].sum[i^d]) % mod;        nd[u].ans[i] = (nd[lson(u)].ans[i] + nd[lson(u)].sum[i] * L % mod + nd[rson(u)].ans[i^d]) % mod;    }}Node query(int u, int l, int r) {    if (l == nd[u].l && nd[u].r == r)        return nd[u];    int mid = (nd[u].l + nd[u].r) / 2;    if (l > mid)        return query(rson(u), l, r);    else if (r <= mid)        return query(lson(u), l, r);    else {        Node ret;        ret.l = l; ret.r = r;        Node lc = query(lson(u), l, mid);        Node rc = query(rson(u), mid + 1, r);        int d = (lc.r - lc.l + 1) & 1;        int L = (rc.r - rc.l + 1) % mod;        for (int i = 0; i < 2; i++) {            ret.sum[i] = (lc.sum[i] + rc.sum[i^d]) % mod;            ret.ans[i] = (lc.ans[i] + lc.sum[i] * L % mod + rc.ans[i^d]) % mod;        }        return ret;    }}void modify (int u, int x, int v) {    if (nd[u].l == nd[u].r) {        nd[u].sum[0] = nd[u].ans[0] = v;        nd[u].sum[1] = nd[u].ans[1] = 0;        return;    }    int mid = (nd[u].l + nd[u].r) / 2;    if (x <= mid)        modify(lson(u), x, v);    if (x > mid)        modify(rson(u), x, v);    pushup(u);}void build_segTree(int u, int l, int r) {    nd[u].l = l; nd[u].r = r;    if (l == r) {        int v = str[(l-1)%N] - '0';        nd[u].sum[0] = nd[u].ans[0] = v;        nd[u].sum[1] = nd[u].ans[1] = 0;        return ;    }    int mid = (l + r) / 2;    build_segTree(lson(u), l, mid);    build_segTree(rson(u), mid + 1, r);    pushup(u);}


Zoj 1610 line segment tree question: Count the Colors why is it always segment fault? Under what circumstances will the segment fault appear?

For example, if the array is small, the subscript of the array is negative, or the stack is exposed recursively, It is deleted by 0 ..


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.