[BZOJ4785][ZJOI2017]树状数组(树套树)
来源:互联网 发布:济南java招聘微信群 编辑:程序博客网 时间:2024/06/11 14:46
可以发现,这个树状数组实际上求的是后缀和。而这样子求出的区间和,只有
这里设
Q:为什么要维护任意两个点相等的概率,而不是维护一个点为
A:这里每个点为
回到问题,考虑一个修改操作对
1、
2、
3、
4、
而询问就是询问
可以用线段树套线段树维护
代码:
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define p2 p << 1#define p3 p << 1 | 1using namespace std;inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res;}const int N = 4e5 + 193, W = 4e7 + 97, PYZ = 998244353;int n, m, rt[N], QAQ;struct cyx { int lc, rc, val; void init() {lc = rc = 0; val = 1;}} T[W];int qpow(int a, int b) { int res = 1; while (b) { if (b & 1) res = 1ll * res * a % PYZ; a = 1ll * a * a % PYZ; b >>= 1; } return res;}int calc(int x, int y) { int res = 1ll * x * y % PYZ, u = 1 - x, v = 1 - y; if (u < 0) u += PYZ; if (v < 0) v += PYZ; return (res + 1ll * u * v % PYZ) % PYZ;}void modify(int l, int r, int s, int e, int v, int &p) { if (!p) T[p = ++QAQ].init(); if (l == s && r == e) return (void) (T[p].val = calc(T[p].val, v)); int mid = l + r >> 1; if (e <= mid) modify(l, mid, s, e, v, T[p].lc); else if (s >= mid + 1) modify(mid + 1, r, s, e, v, T[p].rc); else modify(l, mid, s, mid, v, T[p].lc), modify(mid + 1, r, mid + 1, e, v, T[p].rc);}void change(int l, int r, int s, int e, int st, int ed, int v, int p) { if (l == s && r == e) return modify(1, n, st, ed, v, rt[p]); int mid = l + r >> 1; if (e <= mid) change(l, mid, s, e, st, ed, v, p2); else if (s >= mid + 1) change(mid + 1, r, s, e, st, ed, v, p3); else change(l, mid, s, mid, st, ed, v, p2), change(mid + 1, r, mid + 1, e, st, ed, v, p3);}int query(int l, int r, int x, int p) { if (!p) return 1; int res = T[p].val; if (l == r) return res; int mid = l + r >> 1; if (x <= mid) res = calc(res, query(l, mid, x, T[p].lc)); else res = calc(res, query(mid + 1, r, x, T[p].rc)); return res;}int ask(int l, int r, int x, int y, int p) { int res = query(1, n, y, rt[p]); if (l == r) return res; int mid = l + r >> 1; if (x <= mid) res = calc(res, ask(l, mid, x, y, p2)); else res = calc(res, ask(mid + 1, r, x, y, p3)); return res;}int main() { int i, op, x, y; n = read(); m = read(); while (m--) { op = read(); x = read(); y = read(); if (op == 1) { int v = qpow(y - x + 1, PYZ - 2), w, u = (1 - v + PYZ) % PYZ; if (x > 1) change(0, n, 1, x - 1, x, y, u, 1); if (y < n) change(0, n, x, y, y + 1, n, u, 1); w = (1 - (v << 1) % PYZ + PYZ) % PYZ; change(0, n, x, y, x, y, w, 1); if (x > 1) change(0, n, 0, 0, 1, x - 1, 0, 1); if (y < n) change(0, n, 0, 0, y + 1, n, 0, 1); change(0, n, 0, 0, x, y, v, 1); } else printf("%d\n", ask(0, n, x - 1, y, 1)); } return 0;}
- [BZOJ4785][ZJOI2017]树状数组(树套树)
- [Zjoi2017]bzoj4785 树状数组
- bzoj4785: [Zjoi2017]树状数组
- bzoj4785 UOJ #291 ZJOI2017 Day1 树状数组
- 【ZJOI2017】树状数组 题解
- ZJOI2017 树状数组
- 4785: [Zjoi2017]树状数组
- UOJ#291. 【ZJOI2017】树状数组
- 概率+树套树——UOJ#291/Luogu3688 [ZJOI2017]树状数组
- ZJOI2017游记(雾)
- ZJOI2017
- ZJOI2017
- (转)树状数组
- 树状数组(转载)
- Stars(树状数组)
- 树状数组(interval)
- (转)树状数组
- 树状数组(2)
- Python环境搭建之OpenCV
- 换博客啦!!!
- 求积问题[体会Python至简之道]
- C#委托的异步调用
- 第二次作业答案(官方)
- [BZOJ4785][ZJOI2017]树状数组(树套树)
- 求数组中最大的异或值 20171013
- 下载 sqoop-1.4.4.bin__hadoop-2.0.4-alpha.tar.gz地址
- 笔试_公司(1)
- AndroidStudio导入项目在 Building gradle project info 一直卡住
- 第三次作业答案(官方)
- 关于win和linux双系统,系统时间出错修复
- java基础(九)之深入剖析线程同步Synchronized,Lock
- 关于对getchar一些小小的自学理解。。。