Submission #544510

#TimeUsernameProblemLanguageResultExecution timeMemory
544510model_codeFish 2 (JOI22_fish2)C++17
100 / 100
1784 ms183948 KiB
#include <bits/stdc++.h> using namespace std; #define INF 1000000007 using ll=long long; struct interval{ int l,r; bool operator<(const interval p)const{ return r-l<p.r-p.l; } }; struct SEG_interval{ stack<interval>seg[1<<18]; void add(int a,vector<interval>x){ sort(x.begin(),x.end()); reverse(x.begin(),x.end()); int l=a,r=a; a+=(1<<17)-1; while(1){ while(x.size()>0&&l<=x.back().l&&x.back().r<=r){ seg[a].push(x.back()); x.pop_back(); } if(a==0)break; if(a%2==0)l-=(r-l+1); else r+=(r-l+1); a=(a-1)/2; } } vector<interval> erase(int a){ vector<interval>res; int x=a; a+=(1<<17)-1; while(1){ while(!seg[a].empty()&&seg[a].top().l<=x&&x<=seg[a].top().r){ res.push_back(seg[a].top()); seg[a].pop(); } if(a==0)break; a=(a-1)/2; } return res; } }seg_interval; struct Node{ int mi,cnt; static Node merge(const Node a,const Node b){ Node res; res.mi=min(a.mi,b.mi); res.cnt=0; if(res.mi==a.mi)res.cnt+=a.cnt; if(res.mi==b.mi)res.cnt+=b.cnt; return res; } }; struct SEG_count{ Node seg[1<<18]; int la[1<<18]; SEG_count(){ for(int i=(1<<18)-1;i>=0;i--){ la[i]=0; if(i>=(1<<17)-1)seg[i].mi=0,seg[i].cnt=1; else seg[i]=Node::merge(seg[i*2+1],seg[i*2+2]); } } void eval(int a){ seg[a].mi+=la[a]; if(a<(1<<17)-1){ la[a*2+1]+=la[a]; la[a*2+2]+=la[a]; } la[a]=0; } void add(int a,int b,int x,int k=0,int l=0,int r=(1<<17)-1){ eval(k); if(b<l||r<a)return; if(a<=l&&r<=b){ la[k]+=x; eval(k); return; } add(a,b,x,k*2+1,l,(l+r-1)/2); add(a,b,x,k*2+2,(l+r+1)/2,r); seg[k]=Node::merge(seg[k*2+1],seg[k*2+2]); } Node query(int a,int b,int k=0,int l=0,int r=(1<<17)-1){ eval(k); if(b<l||r<a)return Node{INF,1}; if(a<=l&&r<=b)return seg[k]; return Node::merge(query(a,b,k*2+1,l,(l+r-1)/2),query(a,b,k*2+2,(l+r+1)/2,r)); } }seg_count; struct SEG_others{ ll sum[1<<18]; int ma[1<<18]; SEG_others(){ for(int i=0;i<1<<18;i++)sum[i]=0,ma[i]=0; } void update(int a,int x){ a+=(1<<17)-1; sum[a]=x; ma[a]=x; while(a>0){ a=(a-1)/2; sum[a]=sum[a*2+1]+sum[a*2+2]; ma[a]=max(ma[a*2+1],ma[a*2+2]); } } ll query_sum(int a,int b,int k=0,int l=0,int r=(1<<17)-1){ if(b<l||r<a)return 0; if(a<=l&&r<=b)return sum[k]; return query_sum(a,b,k*2+1,l,(l+r-1)/2)+query_sum(a,b,k*2+2,(l+r+1)/2,r); } int leftest(int a,int x,int k=0,int l=0,int r=(1<<17)-1){ if(r<a||ma[k]<=x)return -1; if(l==r)return l; if(ma[k*2+1]>x){ int res=leftest(a,x,k*2+1,l,(l+r-1)/2); if(res!=-1)return res; } return leftest(a,x,k*2+2,(l+r+1)/2,r); } int rightest(int a,int x,int k=0,int l=0,int r=(1<<17)-1){ if(a<l||ma[k]<=x)return -1; if(l==r)return l; if(ma[k*2+2]>x){ int res=rightest(a,x,k*2+2,(l+r+1)/2,r); if(res!=-1)return res; } return rightest(a,x,k*2+1,l,(l+r-1)/2); } }seg_others; int n,A[100005]; vector<pair<int,ll>>right_cand(int a){ vector<pair<int,ll>>res; ll s=A[a]; while(a<n){ a++; int nxt=seg_others.leftest(a,s); if(nxt==-1)break; res.push_back(make_pair(nxt,seg_others.query_sum(0,nxt))); s+=A[nxt]; a=nxt; } return res; } vector<pair<int,ll>>left_cand(int a){ vector<pair<int,ll>>res; ll s=A[a]; while(a>1){ a--; int nxt=seg_others.rightest(a,s); if(nxt==-1)break; res.push_back(make_pair(nxt,seg_others.query_sum(0,nxt))); s+=A[nxt]; a=nxt; } return res; } void update(int a,int x){ for(int i=-1;i<=1;i++){ vector<interval>del=seg_interval.erase(a+i); for(auto j:del)seg_count.add(j.l,j.r,-1); } A[a]=x; seg_others.update(a,x); vector<pair<int,ll>>right=right_cand(a+1); right.push_back(make_pair(a,seg_others.query_sum(0,a))); right.push_back(make_pair(a+1,seg_others.query_sum(0,a+1))); vector<pair<int,ll>>left=left_cand(a-1); left.push_back(make_pair(a,seg_others.query_sum(0,a))); left.push_back(make_pair(a-1,seg_others.query_sum(0,a-1))); vector<interval>_bad,bad,bad_; for(auto i:left){ for(auto j:right){ int l=i.first,r=j.first; if(l>=r-1)continue; ll s=j.second-A[r]-i.second; if(s<A[l]&&s<A[r]){ l++,r--; seg_count.add(l,r,1); if(l<=a&&a<=r)bad.push_back(interval{l,r}); else if(l<=a-1&&a-1<=r)_bad.push_back(interval{l,r}); else bad_.push_back(interval{l,r}); } } } seg_interval.add(a-1,_bad); seg_interval.add(a+1,bad_); seg_interval.add(a,bad); } int query(int l,int r){ ll l_sum=seg_others.query_sum(0,l-1); vector<pair<int,ll>>right=right_cand(l); for(auto i:right){ if(i.second-l_sum-A[i.first]<A[i.first]&&i.first<=r)l=max(l,i.first); } ll r_sum=seg_others.query_sum(0,r); vector<pair<int,ll>>left=left_cand(r); for(auto i:left){ if(r_sum-i.second<A[i.first]&&i.first>=l)r=min(r,i.first); } return seg_count.query(l,r).cnt; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>A[i]; update(i,A[i]); } int q; cin>>q; while(q--){ int t; cin>>t; if(t==1){ int a,x; cin>>a>>x; update(a,x); }else{ int l,r; cin>>l>>r; cout<<query(l,r)<<endl; } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...