生活随笔
收集整理的這篇文章主要介紹了
线段树平方和板子
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目測試鏈接
代碼
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std
;typedef long long ll
;
typedef unsigned long long ull
;
typedef pair
<int, int> pii
;const double pi
= acos(-1.0);
const double eps
= 1e-7;
const int inf
= 0x3f3f3f3f;inline ll
read() {ll f
= 1, x
= 0;char c
= getchar();while(c
< '0' || c
> '9') {if(c
== '-') f
= -1;c
= getchar();}while(c
>= '0' && c
<= '9') {x
= (x
<< 1) + (x
<< 3) + (c
^ 48);c
= getchar();}return f
* x
;
}void print(ll x
) {if(x
< 10) {putchar(x
+ 48);return ;}print(x
/ 10);putchar(x
% 10 + 48);
}const int N
= 1e5 + 10, mod
= 23333;ll res
[N
<< 2], sum
[N
<< 2], lazy
[N
<< 2];
ll value
[N
];
int head
[N
], to
[N
<< 1], nex
[N
<< 1], cnt
= 1;
int n
, m
, dfn
[N
], sz
[N
], tot
, st
[N
];void add(int x
, int y
) {to
[cnt
] = y
;nex
[cnt
] = head
[x
];head
[x
] = cnt
++;
}void dfs(int rt
, int fa
) {dfn
[++tot
] = rt
;st
[rt
] = tot
;sz
[rt
] = 1;for(int i
= head
[rt
]; i
; i
= nex
[i
]) {if(to
[i
] == fa
) continue;dfs(to
[i
], rt
);sz
[rt
] += sz
[to
[i
]];}
}void push_up(int rt
) {res
[rt
] = (res
[ls
] + res
[rs
]) % mod
;sum
[rt
] = (sum
[ls
] + sum
[rs
]) % mod
;
}void build_tree(int rt
, int l
, int r
) {if(l
== r
) {sum
[rt
] = value
[dfn
[l
]] % mod
;res
[rt
] = (sum
[rt
] * sum
[rt
]) % mod
;return ;}build_tree(lson
);build_tree(rson
);push_up(rt
);
}void push_down(int rt
, int l
, int r
) {if(lazy
[rt
]) {lazy
[ls
] += lazy
[rt
], lazy
[rs
] += lazy
[rt
];res
[ls
] = (res
[ls
] + (((lazy
[rt
] * lazy
[rt
]) % mod
) * (mid
- l
+ 1)) % mod
+ (2ll * sum
[ls
] * lazy
[rt
]) % mod
) % mod
;res
[rs
] = (res
[rs
] + (((lazy
[rt
] * lazy
[rt
]) % mod
) * (r
- mid
)) % mod
+ (2ll * sum
[rs
] * lazy
[rt
]) % mod
) % mod
;sum
[ls
] = (sum
[ls
] + (mid
- l
+ 1) * lazy
[rt
]) % mod
;sum
[rs
] = (sum
[rs
] + (r
- mid
) * lazy
[rt
]) % mod
;lazy
[rt
] = 0;}
}void update(int rt
, int l
, int r
, int L
, int R
, ll k
) {if(l
>= L
&& r
<= R
) {lazy
[rt
] += k
;res
[rt
] = (res
[rt
] + (((k
* k
) % mod
) * (r
- l
+ 1)) % mod
+ (2ll * sum
[rt
] * k
) % mod
) % mod
;sum
[rt
] = (sum
[rt
] + (r
- l
+ 1) * k
) % mod
;return ;}push_down(rt
, l
, r
);if(L
<= mid
) update(lson
, L
, R
, k
);if(R
> mid
) update(rson
, L
, R
, k
);push_up(rt
);
}ll
query(int rt
, int l
, int r
, int L
, int R
){if(l
>= L
&& r
<= R
) return res
[rt
];push_down(rt
, l
, r
);ll ans
= 0;if(L
<= mid
) ans
+= query(lson
, L
, R
);if(R
> mid
) ans
+= query(rson
, L
, R
);return ans
;
}int main() {n
= read(), m
= read();for(int i
= 1; i
<= n
; i
++) value
[i
] = read();for(int i
= 1; i
< n
; i
++) {int x
= read(), y
= read();add(x
, y
);add(y
, x
);}dfs(1, 0);build_tree(1, 1, n
);for(int i
= 1; i
<= m
; i
++) {int op
= read();if(op
== 1) {int x
= read(), y
= read();update(1, 1, n
, st
[x
],st
[x
] + sz
[x
] - 1, y
% mod
);}else {int x
= read();printf("%lld\n", query(1, 1, n
, st
[x
],st
[x
] + sz
[x
] - 1) % mod
);}}return 0;
}
總結
以上是生活随笔為你收集整理的线段树平方和板子的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。