結果
問題 | No.880 Yet Another Segment Tree Problem |
ユーザー |
![]() |
提出日時 | 2023-10-09 18:35:19 |
言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 494 ms / 5,000 ms |
コード長 | 6,314 bytes |
コンパイル時間 | 6,583 ms |
コンパイル使用メモリ | 190,728 KB |
実行使用メモリ | 21,640 KB |
最終ジャッジ日時 | 2025-06-20 11:15:09 |
合計ジャッジ時間 | 16,253 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 38 |
ソースコード
#include <bits/stdc++.h> using namespace std; #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; template<int mod>istream &operator>>(istream &is,static_modint<mod> &a){long long b;is>>b;a=b;return is;} istream &operator>>(istream &is,modint &a){long long b;cin>>b;a=b;return is;} #endif using ll=long long; using ull=unsigned long long; using P=pair<ll,ll>; template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>; template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);} template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);} template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;} template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;} template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;} template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;} template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;} template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;} #define reps(i,a,n) for(int i=(a);i<(n);i++) #define rep(i,n) reps(i,0,n) #define all(x) x.begin(),x.end() #define pcnt(x) __builtin_popcount(x) ll myceil(ll a,ll b){return (a+b-1)/b;} template<typename T,size_t n,size_t id=0> auto vec(const int (&d)[n],const T &init=T()){ if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init)); else return init; } #ifdef LOCAL #include "debug.h" #else #define debug(...) static_cast<void>(0) #define debugg(...) static_cast<void>(0) template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;} #endif void SOLVE(); int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); #ifdef LOCAL clock_t start=clock(); #endif int testcase=1; //cin>>testcase; for(int i=0;i<testcase;i++){ SOLVE(); } #ifdef LOCAL cout<<"time:"; cout<<(clock()-start)/1000; cout<<"ms\n"; #endif } template<typename S,S (*op)(S,S),S (*e)(),typename F,S (*mapping)(F,S),F (*composition)(F,F),F (*id)()> struct SegmentTreeBeats{ private: int m,n,logn; vector<S>data; vector<F>lazy; public: SegmentTreeBeats():SegmentTreeBeats(0){} SegmentTreeBeats(int N):m(N){ n=1,logn=0; while(n<N){ n<<=1; logn++; } data.resize(n*2,e()); lazy.resize(n*2,id()); } SegmentTreeBeats(const vector<S>&a):m((int)a.size()){ n=1,logn=0; while(n<a.size()){ n<<=1; logn++; } data.resize(n*2,e()); lazy.resize(n*2,id()); rep(i,a.size())data[i+n]=a[i]; for(int i=n-1;i>=1;i--)update(i); } void set(int p,S x){ assert(0<=p&&p<m); p+=n; for(int i=logn;i>=1;i--)push(p>>i); data[p]=x; p<<=1; while(p){ update(p); p<<=1; } } S get(int p){ assert(0<=p&&p<m); p+=n; for(int i=logn;i>=1;i--)push(p>>i); return data[p]; } S prod(int l,int r){ assert(0<=l&&l<=r&&r<=m); if(l==r)return e(); l+=n,r+=n; for(int i=logn;i>=1;i--){ if(((l>>i)<<i)!=l)push(l>>i); if(((r>>i)<<i)!=r)push((r-1)>>i); } S lft=e(),rht=e(); while(l<r){ if(l&1)lft=op(lft,data[l++]); if(r&1)rht=op(data[--r],rht); l>>=1,r>>=1; } return op(lft,rht); } S all_prod()const{return data[1];} void apply(int l,int r,F f){ assert(0<=l&&l<=r&&r<=m); if(l==r)return; l+=n,r+=n; for(int i=logn;i>=1;i--){ if(((l>>i)<<i)!=l)push(l>>i); if(((r>>i)<<i)!=r)push((r-1)>>i); } int a=l,b=r; while(l<r){ if(l&1)internalapply(l++,f); if(r&1)internalapply(--r,f); l>>=1,r>>=1; } swap(a,l),swap(b,r); for(int i=1;i<=logn;i++){ if(((l>>i)<<i)!=l)update(l>>i); if(((r>>i)<<i)!=r)update((r-1)>>i); } } private: void internalapply(int p,F f){ data[p]=mapping(f,data[p]); if(p<n){ lazy[p]=composition(f,lazy[p]); if(data[p].fail){ push(p); update(p); } } } void push(int p){ internalapply(p*2,lazy[p]); internalapply(p*2+1,lazy[p]); lazy[p]=id(); } inline void update(int p){data[p]=op(data[p*2],data[p*2+1]);} }; struct S{ ll sum; int sz; ll rangelcm; ll mx; bool fail,same; S():sum(0),sz(0),rangelcm(1),mx(0),fail(false),same(true){} S(ll x):sum(x),sz(1),rangelcm(x),mx(x),fail(false),same(false){} }; S op(S x,S y){ if(x.sz==0)return y; if(y.sz==0)return x; S ret; ret.sum=x.sum+y.sum; ret.sz=x.sz+y.sz; ret.rangelcm=min(1ll<<30,lcm(x.rangelcm,y.rangelcm)); ret.mx=max(x.mx,y.mx); ret.same=x.same&&y.same&&x.mx==y.mx; return ret; } S e(){return S();} struct F{ ll assign; ll rangegcd; F(int type,ll x){ if(type==1){ assign=x; rangegcd=0; } else{ assign=-1; rangegcd=x; } } F():assign(-1),rangegcd(0){} }; S mapping(F f,S x){ if(f.assign==-1&&f.rangegcd==0)return x; if(f.assign!=-1){ S ret=x; ret.mx=f.assign; ret.fail=false; ret.rangelcm=f.assign; ret.sum=f.assign*x.sz; ret.sz=x.sz; ret.same=true; return ret; } if(f.rangegcd%x.rangelcm==0){ return x; } if(x.sz==1){ S ret=x; ret.fail=false; ret.mx=gcd(x.mx,f.rangegcd); ret.sum=ret.mx; ret.rangelcm=ret.mx; ret.sz=1; ret.same=true; return ret; } if(x.same){ S ret=x; ret.mx=gcd(x.mx,f.rangegcd); ret.sum=ret.mx*x.sz; ret.sz=x.sz; ret.fail=false; ret.rangelcm=ret.mx; ret.same=true; return ret; } x.fail=true; return x; } F composition(F f,F g){ if(f.assign!=-1){ return f; } if(g.assign!=-1){ g.assign=min(1ll<<30,gcd(g.assign,f.rangegcd)); return g; } g.rangegcd=min(1ll<<30,gcd(g.rangegcd,f.rangegcd)); return g; } F id(){ return F(); } void SOLVE(){ int n,q; cin>>n>>q; vector<S>a(n); rep(i,n){ ll x; cin>>x; a[i]=S(x); } SegmentTreeBeats<S,op,e,F,mapping,composition,id>seg(a); while(q--){ int t,l,r; cin>>t>>l>>r; l--; if(t<=2){ ll x; cin>>x; seg.apply(l,r,F(t,x)); } else if(t==3){ cout<<seg.prod(l,r).mx<<endl; } else{ cout<<seg.prod(l,r).sum<<endl; } } }