結果
問題 | No.1548 [Cherry 2nd Tune B] 貴方と私とサイクルとモーメント |
ユーザー |
![]() |
提出日時 | 2024-02-23 08:51:01 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 166 ms / 4,500 ms |
コード長 | 7,680 bytes |
コンパイル時間 | 2,262 ms |
コンパイル使用メモリ | 135,148 KB |
最終ジャッジ日時 | 2025-02-19 19:08:40 |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 42 |
ソースコード
#include <iostream>#include <vector>#include <algorithm>#include <array>#include <iterator>#include <string>#include <cctype>#include <cstring>#include <cstdlib>#include <cassert>#include <cmath>#include <ctime>#include <iomanip>#include <numeric>#include <stack>#include <queue>#include <map>#include <unordered_map>#include <set>#include <unordered_set>#include <bitset>#include <random>#include <utility>#include <functional>using namespace std;template<int m> struct modint{private:unsigned int value;static constexpr int mod() {return m;}public:constexpr modint(const long long x = 0) noexcept{long long y = x;if(y < 0 || y >= mod()){y %= mod();if(y < 0) y += mod();}value = (unsigned int)y;}static constexpr int get_mod() noexcept {return m;}static constexpr int primitive_root() noexcept{assert(m == 998244353);return 3;}constexpr unsigned int val() noexcept {return value;}constexpr modint &operator+=(const modint &other) noexcept{value += other.value;if(value >= mod()) value -= mod();return *this;}constexpr modint &operator-=(const modint &other) noexcept{unsigned int x = value;if(x < other.value) x += mod();x -= other.value;value = x;return *this;}constexpr modint &operator*=(const modint &other) noexcept{unsigned long long x = value;x *= other.value;value = (unsigned int) (x % mod());return *this;}constexpr modint &operator/=(const modint &other) noexcept{return *this *= other.inverse();}constexpr modint inverse() const noexcept{assert(value);long long a = value,b = mod(),x = 1,y = 0;while(b){long long q = a/b;a -= q*b; swap(a,b);x -= q*y; swap(x,y);}return modint(x);}constexpr modint power(long long N) const noexcept{assert(N >= 0);modint p = *this,ret = 1;while(N){if(N & 1) ret *= p;p *= p;N >>= 1;}return ret;}constexpr modint operator+() {return *this;}constexpr modint operator-() {return modint() - *this;}constexpr modint &operator++(int) noexcept {return *this += 1;}constexpr modint &operator--(int) noexcept {return *this -= 1;}friend modint operator+(const modint& lhs, const modint& rhs) {return modint(lhs) += rhs;}friend modint operator-(const modint& lhs, const modint& rhs) {return modint(lhs) -= rhs;}friend modint operator*(const modint& lhs, const modint& rhs) {return modint(lhs) *= rhs;}friend modint operator/(const modint& lhs, const modint& rhs) {return modint(lhs) /= rhs;}friend ostream &operator<<(ostream &os,const modint &x) {return os << x.value;}};using mint = modint<998244353>;/* using mint = modint<1000000007>; */template<class T,T (*op)(T,T),T e(),class F,T (*mapping)(F,T),F (*composition)(F,F),F id()> struct LazySegmentTree{private:vector<T> node;vector<F> lazy;int siz,log;void map_and_comp(F f,int u){node[u] = mapping(f,node[u]);if(u < siz) lazy[u] = composition(f,lazy[u]);}void propagate(int u){assert(0 <= u && u < siz);map_and_comp(lazy[u],2*u);map_and_comp(lazy[u],2*u+1);lazy[u] = id();}void recalculate(int u) {node[u] = op(node[2*u],node[2*u+1]);}public:LazySegmentTree(int n = 0) : LazySegmentTree(vector<T>(n,e())) {}LazySegmentTree(const vector<T> &V){siz = 1;log = 0;while(siz < (int)V.size()) siz <<= 1,log++;node.assign(2*siz,e());lazy.assign(siz,id());for(int i = 0;i < (int)V.size();i++) node[i+siz] = V[i];for(int i = siz-1;i >= 1;i--) recalculate(i);}void fill(T x,int l = 0,int r = -1) {if(r < 0){r = siz;} for(int i = l;i < r;i++) replace(i,x);}void clear() {fill(e());}void replace(int pos,T x) {func_update(pos,x,[](T u,T v){return u = v;});}void add(int pos,T x) {func_update(pos,x,[](T u,T v){return u + v;});}void func_update(int pos,T x,T (*func)(T,T)){assert(0 <= pos && pos < siz);pos += siz;for(int i = log;i >= 1;i--) propagate(pos >> i);node[pos] = func(node[pos],x);for(int i = 1;i <= log;i++) recalculate(pos >> i);}T operator[](int pos){assert(0 <= pos && pos < siz);pos += siz;for(int i = log;i >= 1;i--) propagate(pos >> i);return node[pos];}void apply(int pos,F f){assert(0 <= pos && pos < siz);pos += siz;for(int i = log;i >= 1;i--) propagate(pos >> i);node[pos] = mapping(f,node[pos]);for(int i = 1;i <= log;i++) recalculate(pos >> i);}void apply(int l,int r,F f){assert(0 <= l && l <= r && r <= siz);if(l == r) return;l += siz;r += siz;int l0 = l/(l & -l);int r0 = r/(r & -r);for(int i = log;i >= 1;i--) propagate(l0 >> i);for(int i = log;i >= 1;i--) propagate((r0-1) >> i);while(l < r){if(l & 1) map_and_comp(f,l++);if(r & 1) map_and_comp(f,--r);l >>= 1;r >>= 1;}for(int i = 1;i <= log;i++) recalculate(l0 >> i);for(int i = 1;i <= log;i++) recalculate((r0-1) >> i);}T prod() {return node[1];}T prod(int l,int r){assert(0 <= l && l <= r && r <= siz);l += siz;r += siz;int l0 = l/(l & -l);int r0 = r/(r & -r);for(int i = log;i >= 1;i--) propagate(l0 >> i);for(int i = log;i >= 1;i--) propagate((r0-1) >> i);T Lval = e(),Rval = e();while(l < r){if(l & 1) Lval = op(Lval,node[l++]);if(r & 1) Rval = op(node[--r],Rval);l >>= 1;r >>= 1;}return op(Lval,Rval);}};using S = array<mint,5>;S op(S a,S b){for(int i = 0;i < 5;i++){a[i] += b[i];}return a;}S e(){S x;for(int i = 0;i < 5;i++){x[i] = 0;}return x;}S mp(int f,S x){if(f != -1){mint len = x[0];mint p = f;for(int i = 1;i < 5;i++){x[i] = p * len;p *= f;}}return x;}int cp(int f,int g){return f == -1 ? g : f;}int id(){return -1;}void Main(){int N;cin >> N;vector<S> init(N);for(int i = 0;i < N;i++){int a;cin >> a;init[i][0] = 1;for(int j = 1;j < 5;j++){init[i][j] = init[i][j - 1] * a;}}LazySegmentTree<S,op,e,int,mp,cp,id> seg(init);int Q;cin >> Q;for(;Q--;){int t,u,v,w;cin >> t >> u >> v >> w;if(u > v){swap(u,v);}if(t == 0){int b;cin >> b;if(u < w && w < v){seg.apply(u - 1,v,b);}else{seg.apply(v - 1,N,b);seg.apply(0,u,b);}}else{S x;if(u < w && w < v){x = seg.prod(u - 1,v);}else{/* cout << seg.prod(v - 1,N)[0] << " " << seg.prod(0,u)[0] << " " << N - v + 1 << " " << u << "\n"; */x = op(seg.prod(v - 1,N),seg.prod(0,u));}mint L = x[0],M = x[1] / L;mint ans = 0;if(t == 1){}else if(t == 2){ans += x[2];ans -= 2 * M * x[1];ans += M * M * x[0];ans /= L;}else if(t == 3){ans += x[3];ans -= 3 * M * x[2];ans += 3 * M * M * x[1];ans -= M * M * M * x[0];ans /= L;}else{ans += x[4];ans -= 4 * M * x[3];ans += 6 * M * M * x[2];ans -= 4 * M * M * M * x[1];ans += M * M * M * M * x[0];ans /= L;}cout << ans << "\n";}}}int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int tt = 1;/* cin >> tt; */while(tt--) Main();}