update
This commit is contained in:
parent
90dd8348fe
commit
690b11e039
103
src/20241111/U101804.cpp
Normal file
103
src/20241111/U101804.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <ranges>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define func auto
|
||||||
|
|
||||||
|
using i64 = int64_t;
|
||||||
|
using i32 = int32_t;
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
void input(Args&&...args){
|
||||||
|
(std::cin>>...>>args);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T input(){
|
||||||
|
T tmp;
|
||||||
|
std::cin>>tmp;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
func print(Args...args){
|
||||||
|
(std::cout<<...<<args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const i64 max_n = 100000 + 5, mod{998244353};
|
||||||
|
i64 w[max_n], a[max_n];
|
||||||
|
std::vector<i64> sons[max_n];
|
||||||
|
|
||||||
|
i64 mod_pow(i64 b, i64 e, const i64 m = mod){
|
||||||
|
b %= mod;
|
||||||
|
i64 res {1};
|
||||||
|
while(e!=0){
|
||||||
|
if(e&1){
|
||||||
|
res = (res * b) % mod;
|
||||||
|
}
|
||||||
|
b = (b * b) % mod;
|
||||||
|
e>>=1;
|
||||||
|
}
|
||||||
|
return res % mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 inverse(const i64 b, const i64 m = mod){
|
||||||
|
return mod_pow(b, m-2, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 mult_mod(const i64 a, const i64 b, const i64 m = mod){
|
||||||
|
return ((a % m) * inverse(b)) % m;
|
||||||
|
}
|
||||||
|
|
||||||
|
func dfs(const i64 u, const i64 prob)->i64{
|
||||||
|
if(sons[u].empty()){
|
||||||
|
return (prob * a[u]) % mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
const i64 sum_u = [&u]()->i64{
|
||||||
|
i64 ret{};
|
||||||
|
for(const i64 v:sons[u]){
|
||||||
|
ret = (ret + w[v]) % mod;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}();
|
||||||
|
|
||||||
|
const i64 exp_score = [&prob, &sum_u, &u]()->i64{
|
||||||
|
i64 ret {};
|
||||||
|
for(const auto v:sons[u]){
|
||||||
|
// const i64 new_prob = prob * w[v] / sum_u;
|
||||||
|
const i64 new_prob = mult_mod(prob * w[v], sum_u);
|
||||||
|
ret = (ret + dfs(v, new_prob)) % mod;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return (exp_score + prob * a[u]) % mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
func main()->int{
|
||||||
|
const i64 n = input<i64>();
|
||||||
|
for(const i64 i:std::ranges::views::iota(2,n+1)){
|
||||||
|
const i64 father = input<i64>();
|
||||||
|
sons[father].push_back(i);
|
||||||
|
}
|
||||||
|
std::for_each_n(w+1, n,[](i64 &wi){
|
||||||
|
input(wi);
|
||||||
|
});
|
||||||
|
std::for_each_n(a+1, n, [](i64 &ai){
|
||||||
|
input(ai);
|
||||||
|
});
|
||||||
|
|
||||||
|
print(dfs(1, 1), '\n');
|
||||||
|
|
||||||
|
const i64 q = input<i64>();
|
||||||
|
|
||||||
|
std::ranges::for_each(std::ranges::views::iota(0ll, q), [](auto){
|
||||||
|
const i64 u{input<i64>()};
|
||||||
|
w[u] = input<i64>();
|
||||||
|
a[u] = input<i64>();
|
||||||
|
print(dfs(1,1),'\n');
|
||||||
|
});
|
||||||
|
}
|
@ -45,7 +45,7 @@ i64 inverse(const i64 b, const i64 m = mod){
|
|||||||
return mod_pow(b, m-2, m);
|
return mod_pow(b, m-2, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 times_mod(const i64 a, const i64 b, const i64 m = mod){
|
i64 mult_mod(const i64 a, const i64 b, const i64 m = mod){
|
||||||
return ((a % m) * inverse(b)) % m;
|
return ((a % m) * inverse(b)) % m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ i64 dfs(const i64 u, const i64 prob){
|
|||||||
i64 ret {};
|
i64 ret {};
|
||||||
for(const auto v:sons[u]){
|
for(const auto v:sons[u]){
|
||||||
// const i64 new_prob = prob * w[v] / sum_u;
|
// const i64 new_prob = prob * w[v] / sum_u;
|
||||||
const i64 new_prob = times_mod(prob * w[v], sum_u);
|
const i64 new_prob = mult_mod(prob * w[v], sum_u);
|
||||||
ret = (ret + dfs(v, new_prob)) % mod;
|
ret = (ret + dfs(v, new_prob)) % mod;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
147
src/P3372/P3372.cpp
Normal file
147
src/P3372/P3372.cpp
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <istream>
|
||||||
|
#include <ranges>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using i64 = int64_t;
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
void input(Args&&...args){
|
||||||
|
(std::cin>>...>>std::forward<Args>(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
void print(Args&&...args){
|
||||||
|
((std::cout<<args<<' '), ...);
|
||||||
|
std::cout<<'\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::remove_cvref_t<T> input(){
|
||||||
|
std::remove_cvref_t<T> tmp;
|
||||||
|
std::cin>>tmp;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class _T>
|
||||||
|
struct SegTree{
|
||||||
|
using T = std::remove_cvref_t<_T>;
|
||||||
|
static_assert(std::is_integral_v<T>, "Please use number-like type");
|
||||||
|
|
||||||
|
const i64 size;
|
||||||
|
std::vector<T> tree;
|
||||||
|
std::vector<T> lazy;
|
||||||
|
|
||||||
|
SegTree(const std::vector<T> &arr):size(arr.size()), tree(arr.size()*4, T{}), lazy(arr.size()*4, T{}){
|
||||||
|
init(arr, 0, arr.size()-1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(const i64 ul, const i64 ur, const i64 val){
|
||||||
|
update(ul, ur, 0, size-1, 0, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard("Do not forget to use the result of query")]] T query(const i64 ql, const i64 qr){
|
||||||
|
return query(ql, qr, 0, size-1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init(const std::vector<T> &arr, const i64 l, const i64 r, const i64 n){
|
||||||
|
if(l==r){
|
||||||
|
tree[n] = arr[l];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const i64 mid = (l+r)/2;
|
||||||
|
|
||||||
|
init(arr, l, mid, n*2+1);
|
||||||
|
init(arr, mid+1, r, n*2+2);
|
||||||
|
|
||||||
|
tree[n] = tree[n*2+1] + tree[n*2+2];
|
||||||
|
}
|
||||||
|
|
||||||
|
T query(const i64 ql, const i64 qr, const i64 l, const i64 r, const i64 n){
|
||||||
|
if(lazy[n]!=0){
|
||||||
|
tree[n] += lazy[n] * (r-l+1);
|
||||||
|
if(l!=r){
|
||||||
|
lazy[n*2+1] += lazy[n];
|
||||||
|
lazy[n*2+2] += lazy[n];
|
||||||
|
}
|
||||||
|
lazy[n]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(qr < l || r < ql){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ql<=l && r<=qr){
|
||||||
|
return tree[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
const i64 mid{(l+r)/2};
|
||||||
|
|
||||||
|
T ret{};
|
||||||
|
|
||||||
|
ret+=query(ql, qr, l, mid, n*2+1);
|
||||||
|
ret+=query(ql, qr, mid+1, r, n*2+2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(const i64 ul, const i64 ur, const i64 l, const i64 r, const i64 n, const T val){
|
||||||
|
if(lazy[n]!=0){
|
||||||
|
tree[n] += lazy[n] * (r-l+1);
|
||||||
|
if(l!=r){
|
||||||
|
lazy[n*2+1] += lazy[n];
|
||||||
|
lazy[n*2+2] += lazy[n];
|
||||||
|
}
|
||||||
|
lazy[n]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ur < l || r < ul){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ul <= l && r <= ur){
|
||||||
|
tree[n] += (r-l+1)*val;
|
||||||
|
if(l!=r){
|
||||||
|
lazy[n*2+1] += val;
|
||||||
|
lazy[n*2+2] += val;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const i64 mid = (l+r)/2;
|
||||||
|
|
||||||
|
update(ul, ur, l, mid, n*2+1, val);
|
||||||
|
update(ul, ur, mid+1, r, n*2+2, val);
|
||||||
|
tree[n] = tree[n*2+1] + tree[n*2+2];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
std::iostream::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
|
||||||
|
|
||||||
|
const i64 n{input<decltype(n)>()}, m{input<decltype(m)>()};
|
||||||
|
|
||||||
|
std::vector<i64> arr(n);
|
||||||
|
std::for_each(arr.begin(), arr.end(), [](auto &i){
|
||||||
|
input(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
SegTree<i64> st(arr);
|
||||||
|
|
||||||
|
std::ranges::for_each(std::ranges::views::iota(0,m), [&st](auto){
|
||||||
|
const i64 k{input<decltype(k)>()};
|
||||||
|
if(k==1){
|
||||||
|
const i64 x{input<i64>()-1}, y{input<i64>()-1}, val{input<i64>()};
|
||||||
|
st.update(x, y, val);
|
||||||
|
}else{
|
||||||
|
const i64 x{input<i64>()-1}, y{input<i64>()-1};
|
||||||
|
print(st.query(x, y));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user