noip模擬41(待補)
阿新 • • 發佈:2021-08-19
A. 你相信引力嗎
\(Sort+Map+\)連結串列 亂搞搞了\(80pts\).
考時程式碼
#include<bits/stdc++.h> using namespace std; namespace BSS { #define ll long long int #define ull unsigend ll #define re register ll #define lf double #define lbt(x) (x&(-x)) #define mp(x,y) make_pair(x,y) #define lb lower_bound #define ub upper_bound #define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout) #define Fill(x,y) memset(x,y,sizeof x) #define Copy(x,y) memcpy(x,y,sizeof x) inline ll read() { ll ss=0; bool cit=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') cit=0; while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar(); return cit?ss:-ss; } } using namespace BSS; const ll N=5e6+51; ll m,n,cnt,tail,ts,maxn,ans; ll h[N],lsh[N],stk[N],nxt[N],t[N],head[N]; struct I { ll l,r; } p[N]; inline ll inc(ll i,ll j){ return i+j>n ? i+j-n : i+j ; } signed main(){ n=read(); ll l,r,temp; for(re i=1;i<=n;i++) lsh[i]=h[i]=read(); sort(lsh+1,lsh+1+n); cnt=unique(lsh+1,lsh+1+n)-lsh-1; for(re i=1;i<=n;i++) h[i]=lb(lsh+1,lsh+1+cnt,h[i])-lsh,maxn=max(h[i],maxn); for(re i=1;i<=n;i++) if(h[i]==maxn) { temp=i; break; } for(re i=1;i<=n;i++) t[i]=h[inc(temp-1,i)]; for(re i=1;i<=n;i++) h[i]=t[i]; for(re i=1;i<=n;i++) if(!tail){ p[i].l=i,stk[++tail]=i; } else{ if(h[stk[tail]]>h[i]) p[i].l=i,stk[++tail]=i; else if(h[stk[tail]]==h[i]) p[i].l=p[stk[tail]].l,stk[++tail]=i; else{ r=i-1,l=N; while(tail and h[stk[tail]]<h[i]){ temp=stk[tail--],p[temp].r=i-1, l=p[temp].l; } if(h[stk[tail]]==h[i]) p[i].l=min(l,p[stk[tail]].l); else p[i].l=l; stk[++tail]=i; } } while(tail) temp=stk[tail--],p[temp].r=n; // for(re i=1;i<=n;i++) cout<<lsh[h[i]]<<' '; // cout<<'\n'; // for(re i=1;i<=n;i++) cout<<p[i].l<<" "<<p[i].r<<'\n'; for(re i=n;i>=1;i--) nxt[i]=head[h[i]],head[h[i]]=i; ll res=0; for(re i=1;i<=n;i++) if(h[i]==h[1]) res++; ans+=res*(res-1)/2; temp=head[cnt-1]; while(temp){ res=1; while(nxt[temp]&&p[nxt[temp]].l==p[temp].l&&p[nxt[temp]].r==p[temp].r){ res++,temp=nxt[temp]; } ans+=res*(res-1)/2+res+res*(ans>0),temp=nxt[temp]; } // cout<<"ans:"<<ans<<endl; for(re i=cnt-2;i>=1;i--){ temp=head[i]; while(temp){ // cout<<lsh[i]<<' '; res=1; while(nxt[temp]&&p[nxt[temp]].l==p[temp].l&&p[nxt[temp]].r==p[temp].r){ res++,temp=nxt[temp]; } // cout<<"res:"<<res<<endl; ans+=res*(res-1)/2+res*2,temp=nxt[temp]; } } printf("%lld\n",ans); return 0; }