W - Doom HDU - 5239 modulo segment tree to find a great demand law + square of the wording of a special number modulo the modulus == ^ 2 ^ 63-2 31

The subject or start to feel a bit difficult, and this module is so big, do not know how to write, and then went to search for a solution to a problem, know how to find the square when the time x x large sample of how a number of modulo not ringing off the hook.

Then also the way the law is found in a number of updates after a certain number will not be changed.

Then the subject was well written, and a summation interval is a range of modifications. It is not certain if we do not find a law is not time out.

 

Now finished, you will find the process of writing, this must be updated each time to a leaf node can, otherwise this is a problem, because we require and,

So if you do not update to a leaf node, it can not be summed, and then we calculate the complexity, if direct is m * n * logn then the complexity is too high

With this law but after you will find each of the maximum number of times on the same square 30, so that is the complexity is 30 * n * logn this will be accepted.

So this law is very important, after you know this very well written.

This module can be a bit special note about 31 ^ 2 ^ 63-2

 

#include <cstring>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5 + 10;
typedef unsigned long long ull;
typedef long long ll;
const ull mod = 9223372034707292160;
ll q_mul(ll a, ll b) {
    ll ans = 0;
    while (b) {
        if (b & 1) {
            ans = (ans + a) % mod;
        }
        a = (a + a) % mod;
        b >>= 1;
    }
    return ans;
}
ull a[maxn], sum[maxn * 8], flag[maxn * 8];

void push_up(int id) {
    sum[id] = (sum[id << 1] + sum[id << 1 | 1]) % mod;
    if (flag[id << 1] && flag[id << 1 | 1]) flag[id] = 1;
}

void build(int id, int l, int r) {
    flag[id] = 0;
    if (l == r) {
        sum[id] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
    push_up(id);
}

ull query(int id, int l, int r, int x, int y) {
    if (x <= l && y >= r) return sum[id];
    int mid = (l + r) >> 1;
    ull ans = 0;
    if (x <= mid) ans += query(id << 1, l, mid, x, y) % mod, ans%mod;
    if (y > mid) ans += query(id << 1 | 1, mid + 1, r, x, y) % mod, ans %= mod;
    return ans % mod;
}

void update(int id, int l, int r, int x, int y) {
    if (flag[id]) return;
    if (l == r) {
        ull ans = q_mul(sum[id], sum[id]);
        if (ans == sum[id]) flag[id] = 1;
        sum[id] = ans;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) update(id << 1, l, mid, x, y);
    if (y > mid) update(id << 1 | 1, mid + 1, r, x, y);
    push_up(id);
}


int main() {
    int t;
    scanf("%d", &t);
    for (int cas = 1; cas <= t; cas++) {
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%llu", &a[i]);
        build(1, 1, n);
        ull ans = 0;
        printf("Case #%d:\n", cas);
        while (m--) {
            int l, r;
            scanf("%d%d", &l, &r);
            ans += query(1, 1, n, l, r);
            ans %= mod;
            printf("%llu\n", ans);
            update(1, 1, n, l, r);
        }
    }
    return 0;
}
Segment tree to find the law +

 

Guess you like

Origin www.cnblogs.com/EchoZQN/p/11297386.html