diff --git a/src/20241111/U101804.cpp b/src/20241111/U101804.cpp new file mode 100644 index 0000000..e7b85f7 --- /dev/null +++ b/src/20241111/U101804.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#define func auto + +using i64 = int64_t; +using i32 = int32_t; + +template +void input(Args&&...args){ + (std::cin>>...>>args); +} + +template +T input(){ + T tmp; + std::cin>>tmp; + return tmp; +} + +template +func print(Args...args){ + (std::cout<<...< 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(); + for(const i64 i:std::ranges::views::iota(2,n+1)){ + const i64 father = input(); + 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(); + + std::ranges::for_each(std::ranges::views::iota(0ll, q), [](auto){ + const i64 u{input()}; + w[u] = input(); + a[u] = input(); + print(dfs(1,1),'\n'); + }); +} \ No newline at end of file diff --git a/src/20241111/U101804_low.cpp b/src/20241111/U101804_low.cpp index d40e97b..3856b85 100644 --- a/src/20241111/U101804_low.cpp +++ b/src/20241111/U101804_low.cpp @@ -45,7 +45,7 @@ i64 inverse(const i64 b, const i64 m = mod){ 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; } @@ -66,7 +66,7 @@ i64 dfs(const i64 u, const i64 prob){ i64 ret {}; for(const auto v:sons[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; } return ret; diff --git a/src/P3372/P3372.cpp b/src/P3372/P3372.cpp new file mode 100644 index 0000000..5ae0df0 --- /dev/null +++ b/src/P3372/P3372.cpp @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using i64 = int64_t; + +template +void input(Args&&...args){ + (std::cin>>...>>std::forward(args)); +} + +template +void print(Args&&...args){ + ((std::cout< +std::remove_cvref_t input(){ + std::remove_cvref_t tmp; + std::cin>>tmp; + return tmp; +} + +template +struct SegTree{ + using T = std::remove_cvref_t<_T>; + static_assert(std::is_integral_v, "Please use number-like type"); + + const i64 size; + std::vector tree; + std::vector lazy; + + SegTree(const std::vector &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 &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()}, m{input()}; + + std::vector arr(n); + std::for_each(arr.begin(), arr.end(), [](auto &i){ + input(i); + }); + + SegTree st(arr); + + std::ranges::for_each(std::ranges::views::iota(0,m), [&st](auto){ + const i64 k{input()}; + if(k==1){ + const i64 x{input()-1}, y{input()-1}, val{input()}; + st.update(x, y, val); + }else{ + const i64 x{input()-1}, y{input()-1}; + print(st.query(x, y)); + } + }); +} \ No newline at end of file