제출 #1130730

#제출 시각아이디문제언어결과실행 시간메모리
1130730StefanSebez송신탑 (IOI22_towers)C++20
100 / 100
1671 ms42388 KiB
#include <bits/stdc++.h> #include "towers.h" using namespace std; #define fi first #define se second #define pb push_back #define ll long long #define ld long double const int N=1e5+50,lg=17; const ll inf=2e9+50; int n,a[N]; int Maks[N][lg+1],LOG[N+50]; int MAKS(int l,int r){if(l>r)return 0;int i=LOG[r-l+1];return max(Maks[l][i],Maks[r-(1<<i)+1][i]);} int Lm[N],Rm[N]; vector<pair<ll,ll>>nesto; int root[N]; struct PersistentSegTree{ int nc,lc[N*(lg+5)],rc[N*(lg+5)],sum[N*(lg+5)]; void Update(int &c,int c1,int ss,int se,int qind,int x){ c=++nc;lc[c]=lc[c1],rc[c]=rc[c1],sum[c]=sum[c1]; if(ss==se){sum[c]=x;return;} int mid=ss+se>>1; if(qind<=mid) Update(lc[c],lc[c1],ss,mid,qind,x); else Update(rc[c],rc[c1],mid+1,se,qind,x); sum[c]=sum[lc[c]]+sum[rc[c]]; } int Get(int c,int ss,int se,int qs,int qe){ if(qs>qe||qe<ss||se<qs)return 0; if(qs<=ss&&se<=qe)return sum[c]; int mid=ss+se>>1;return Get(lc[c],ss,mid,qs,qe)+Get(rc[c],mid+1,se,qs,qe); } }PST; struct Node{ll maks,mn,ind,val1,val2;}; Node Merge(Node a,Node b){ Node c; c.maks=max(a.maks,b.maks); c.mn=min(a.mn,b.mn); if(a.mn<=b.mn) c.ind=a.ind; else c.ind=b.ind; c.val1=max({a.val1,b.val1,b.maks-a.mn}); c.val2=max({a.val2,b.val2,a.maks-b.mn}); return c; } struct SegTree1{ int root,nc,lc[2*N],rc[2*N];Node node[2*N]; void Build(int &c,int ss,int se){ c=++nc; if(ss==se){node[c]={a[ss],a[ss],ss,0,0};return;} int mid=ss+se>>1; Build(lc[c],ss,mid),Build(rc[c],mid+1,se); node[c]=Merge(node[lc[c]],node[rc[c]]); } Node Get(int c,int ss,int se,int qs,int qe){ if(qs>qe||qe<ss||se<qs)return {0,inf,0,0}; if(qs<=ss&&se<=qe)return node[c]; int mid=ss+se>>1;return Merge(Get(lc[c],ss,mid,qs,qe),Get(rc[c],mid+1,se,qs,qe)); } }ST1; void init(int N, std::vector<int> H){ n=N; for(int i=1;i<=n;i++) a[i]=H[i-1]; for(int i=1,e=1,ct=-1;i<=N;i++){if(i==e)e<<=1,ct++;LOG[i]=ct;} for(int i=1;i<=n;i++) Maks[i][0]=a[i]; for(int j=0;j<lg;j++) for(int i=1;i<=n;i++) if(i+(1<<j)<=n) Maks[i][j+1]=max(Maks[i][j],Maks[i+(1<<j)][j]); vector<int>mono; for(int i=1;i<=n;i++){ Lm[i]=0,Rm[i]=n+1; while(!mono.empty()&&a[mono.back()]>a[i]){ Rm[mono.back()]=i; mono.pop_back(); } if(!mono.empty()) Lm[i]=mono.back(); mono.pb(i); } for(int i=1;i<=n;i++){ ll x=inf,y=inf; if(Lm[i]>0) x=MAKS(Lm[i]+1,i-1); if(Rm[i]<=n) y=MAKS(i+1,Rm[i]-1); nesto.pb({min(x,y)-a[i],i}); } sort(nesto.begin(),nesto.end()); reverse(nesto.begin(),nesto.end()); for(int i=0;i<nesto.size();i++) PST.Update(root[i+1],root[i],1,n,nesto[i].se,1); ST1.Build(ST1.root,1,n); } int max_towers(int L, int R, int D){ L++,R++; int l=0,r=n-1,ind,rt; while(l<=r){ int mid=l+r>>1; if(nesto[mid].fi>=D){ind=mid;l=mid+1;} else r=mid-1; } rt=root[ind+1]; int res=PST.Get(rt,1,n,L,R); if(res==0) res=1; l=L,r=R; int levo=ST1.Get(ST1.root,1,n,L,R).ind; while(l<=r){ int mid=l+r>>1; int x=PST.Get(rt,1,n,L,mid); if(x>0){levo=mid;r=mid-1;} else l=mid+1; } l=L,r=levo-1; int L1=L-1; while(l<=r){ int mid=l+r>>1; ll x=MAKS(mid,levo-1); if(x-D>=a[levo]){L1=mid;l=mid+1;} else r=mid-1; } if(ST1.Get(ST1.root,1,n,L,L1).val1>=D) res++; l=L,r=R; int desno=ST1.Get(ST1.root,1,n,L,R).ind; while(l<=r){ int mid=l+r>>1; int x=PST.Get(rt,1,n,mid,R); if(x>0){desno=mid;l=mid+1;} else r=mid-1; } l=desno+1,r=R; int R1=R+1; while(l<=r){ int mid=l+r>>1; ll x=MAKS(desno+1,mid); if(x-D>=a[desno]){R1=mid;r=mid-1;} else l=mid+1; } if(ST1.Get(ST1.root,1,n,R1,R).val2>=D) res++; return res; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...