제출 #639373

#제출 시각아이디문제언어결과실행 시간메모리
639373inksamuraiGaraža (COCI17_garaza)C++17
160 / 160
2189 ms48064 KiB
#include <bits/stdc++.h> #define int ll using namespace std; #define rep(i,n) for(int i=0;i<n;i++) #define per(i,n) for(int i=n-1;i>=0;i--) #define rng(i,c,n) for(int i=c;i<n;i++) #define fi first #define se second #define pb push_back #define sz(a) (int)a.size() #define vec(...) vector<__VA_ARGS__> #define _3xaMC2q ios::sync_with_stdio(0),cin.tie(0) typedef long long ll; using pii=pair<int,int>; using vi=vector<int>; void print(){cout<<'\n';} template<class h,class...t> void print(const h&v,const t&...u){cout<<v<<' ',print(u...);} //e using vp=vec(pii); struct N{ int val,len; vp fr,bk; N(int _val=0,int _len=0,vp vc={}): val(_val),len(_len),fr(vc),bk(vc){} }; int f(int si,int n){ return si*n-(n*(n-1))/2; } struct segtree{ int n; vec(N) seg; segtree(int _n=0){ init(_n); } void init(int _n){ n=_n; seg.resize(n*4); } N merge(N l,N r){ if(!sz(l.fr)){ return r; }else if(!sz(r.fr)){ return l; } N res; res.val=l.val+r.val; res.len=l.len+r.len; vec(pii) leftover; //from back to front rep(i,sz(l.bk)){ //gcd int g=l.bk[i].se; if(g==1) continue; //suffix sum in l node int now=0; per(j,i+1){ now+=l.bk[j].fi; } bool pok=0; rep(j,sz(r.fr)){ g=gcd(g,r.fr[j].se); if(g==1){ pok=1; res.val+=f(now,l.bk[i].fi); break; } now+=r.fr[j].fi; } if(!pok){ leftover.pb(l.bk[i]); } } res.bk=r.bk; //from leftover should be pushed in res.bk if(sz(leftover)){ int g=0; rep(i,sz(r.bk)){ g=gcd(g,r.bk[i].se); } vec(pii) rbts=res.bk; rep(i,sz(leftover)){ g=gcd(g,leftover[i].se); assert(g!=-1); if(g==rbts.back().se){ rbts.back().fi+=leftover[i].fi; }else{ rbts.pb(pii(leftover[i].fi,g)); } } res.bk=rbts; } res.fr=l.fr; //merge front of l node with r.bk { int now=0,g=0; rep(i,sz(l.fr)){ now+=l.fr[i].fi; g=gcd(g,l.fr[i].se); } if(now==l.len and g!=1){ rep(i,sz(r.fr)){ g=gcd(g,r.fr[i].se); if(g==res.fr.back().se){ res.fr.back().fi+=r.fr[i].fi; }else{ res.fr.pb(pii(r.fr[i].fi,g)); } if(g==1) break; } } } return res; } void set(int node,int l,int r,int pos,int v){ if(l==r-1){ seg[node].fr.clear(); seg[node].bk.clear(); seg[node]=N(0,1,{{1,v}}); return; } int m=(l+r)/2; if(pos<m){ set(node*2+1,l,m,pos,v); }else{ set(node*2+2,m,r,pos,v); } seg[node]=merge(seg[node*2+1],seg[node*2+2]); } void set(int pos,int v){ set(0,0,n,pos,v); } N prod(int node,int l,int r,int _l,int _r){ if(l>=_r or r<=_l){ return N(); } if(_l<=l and r<=_r){ return seg[node]; } int m=(l+r)/2; N vl=prod(node*2+1,l,m,_l,_r); N vr=prod(node*2+2,m,r,_l,_r); return merge(vl,vr); } int prod(int l,int r){ N res=prod(0,0,n,l,r); int ans=res.val; int now=0; for(auto p:res.bk){ if(p.se==1) break; // print("go",p.se); now+=p.fi; ans+=f(now,p.fi); } return ans; } }; signed main(){ _3xaMC2q; int n,q; cin>>n>>q; vi a(n); rep(i,n){ cin>>a[i]; } segtree seg(n); rep(i,n){ seg.set(i,a[i]); } // print(seg.prod(0,n)); rep(i,q){ int t; cin>>t; if(t==2){ int l,r; cin>>l>>r; l-=1; print(seg.prod(l,r)); }else{ int id,v; cin>>id>>v; id-=1; seg.set(id,v); } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...