QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#352776#7992. 【模板】线段树WTR2007RE 0ms0kbC++203.4kb2024-03-13 16:39:052024-03-13 16:39:06

Judging History

你现在查看的是最新测评结果

  • [2024-03-13 16:39:06]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-03-13 16:39:05]
  • 提交

answer

#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define L (p << 1)
#define R (p << 1 | 1)
#define mid ((l + r) >> 1)
#define fi first
#define se second
#define MULT_TEST 0
using namespace std;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = (1ll << 20);
const int N = 200005, M = 25;
struct Seg {
    int C[M], tag;
} tr[N << 2];
int bit[M][M], a[N], pom[M];
const int Z = 1 << 20;
char buf[Z], *p1 = buf, *p2 = buf;
inline int getc() {
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, Z, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read() {
    int x = 0;
    char ch = getc();
    while (!isdigit(ch)) ch = getc();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getc();
    return x;
}
inline void add(int &x, int y) {
    x += y;
    if (x >= MOD) x -= MOD;
}
inline Seg Merge(Seg A, Seg B) {
    Seg ans;
    for (int i = 0; i <= 20; i++) ans.C[i] = 0;
    ans.tag = 0;
    for (int i = 0; i <= 20; i++) {
        for (int j = 0; j <= 20; j++) {
            if (i + j > 20) continue;
            add(ans.C[i + j], 1ll * A.C[i] * B.C[j] % MOD);
        }
    }
    return ans;
}
inline Seg Add(Seg x, int y) {
    pom[0] = 1;
    for (int i = 1; i <= 20; i++) 
        pom[i] = 1ll * pom[i - 1] * y % MOD;
    for (int i = 0; i <= 20; i++) 
        for (int j = i + 1; j <= 20; j++) 
            add(x.C[i], 1ll * x.C[j] * pom[j - i] % MOD * bit[j][j - i] % MOD);
    add(x.tag, y);
}
inline void Pushup(int p) {
    tr[p] = Merge(tr[L], tr[R]);
}
inline void Pushdown(int p) {
    if (tr[p].tag) {
        tr[L] = Add(tr[L], tr[p].tag);
        tr[R] = Add(tr[R], tr[p].tag);
        tr[p].tag = 0;
    }
}
inline void Modify(int p, int l, int r, int ql, int qr, int d) {
    if (ql <= l && r <= qr) {
        tr[p] = Add(tr[p], d);
        return ;
    }
    Pushdown(p);
    if (ql <= mid) Modify(L, l, mid, ql, qr, d);
    if (qr > mid) Modify(R, mid + 1, r, ql, qr, d);
    Pushup(p);
}
inline Seg Query(int p, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return tr[p];
    Pushdown(p);
    if (qr <= mid) return Query(L, l, mid, ql, qr);
    else if (ql > mid) return Query(R, mid + 1, r, ql, qr);
    else {
        Seg ans = Merge(Query(L, l, mid, ql, qr), Query(R, mid + 1, r, ql, qr));
        return ans;
    }
}
inline void Build(int p, int l, int r) {
    for (int i = 0; i <= 20; i++) tr[p].C[i] = 0;
    tr[p].tag = 0;
    if (l == r) {
        tr[p].C[1] = 1;
        tr[p].C[0] = a[l];
        return ;
    }
    Build(L, l, mid);
    Build(R, mid + 1, r);
    Pushup(p);
}
inline void Solve() {
    int n, q;
    n = read(); q = read();
    for (int i = 1; i <= n; i++) a[i] = read();
    Build(1, 1, n);
    for (int i = 0; i <= 20; i++) {
        for (int j = 0; j <= i; j++) {
            if (j == 0 || j == i) bit[i][j] = 1;
            else bit[i][j] = (bit[i - 1][j] + bit[i - 1][j - 1]) % MOD;
        }
    }
    while (q--) {
        int op = read(), l = read(), r = read();
        if (op == 1) {
            int x = read();
            if (x != 0) Modify(1, 1, n, l, r, x);
        }
        else {
            Seg ans = Query(1, 1, n, l, r);
            printf("%lld\n", ans.C[0]);
        }
    }
}
signed main() {
    int _ = 1;
#if MULT_TEST
    _ = read();
#endif 
    while (_--) Solve();
    return 0;
}

详细

Test #1:

score: 0
Runtime Error

input:

10 10
969575 741825 24903 1047319 450475 256145 1045323 479255 810659 768323
1 5 6 3034
2 1 10
2 1 9
2 1 4
1 3 6 126904
2 5 5
2 9 9
1 7 7 853094
1 4 9 1025178
2 5 8

output:


result: