This commit is contained in:
Zengtudor 2024-11-12 17:02:08 +08:00
parent 90dd8348fe
commit 690b11e039
3 changed files with 252 additions and 2 deletions

103
src/20241111/U101804.cpp Normal file
View 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');
});
}

View File

@ -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
View 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));
}
});
}