noip模拟41
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;
}
正解还是单调栈,只不过是在栈的过程中求解,所以去掉了一个 \(log\).
A_code
#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,tail,lm,maxn,ans,maxcnt;
ll h[N],stk[N],t[N],sum[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=0;
for(re i=1;i<=n;++i) h[i]=read(),maxn=max(h[i],maxn);
for(re i=1;i<=n;++i) if(h[i]==maxn) { if(!temp) temp=i; maxcnt++;}
for(re i=1;i<=n;++i) if(h[i]!=maxn) lm=max(lm,h[i]);
for(re i=1;i<=n;++i) t[i]=h[inc(temp-1,i)]; Copy(h,t);
for(re i=1;i<=n;++i){
if((!tail) or stk[tail]>h[i]) stk[++tail]=h[i],++sum[tail];
else{
if(stk[tail]==h[i]) ++sum[tail];
else{
while(tail and stk[tail]<h[i]){
ans+=sum[tail]*(sum[tail]-1)/2+sum[tail]*2,sum[tail--]=0;
}
if(tail and h[i]==stk[tail]) ++sum[tail];
else stk[++tail]=h[i],++sum[tail];
}
}
}
while(tail){
if(stk[tail]==maxn) ans+=sum[tail]*(sum[tail]-1)/2,sum[tail--]=0;
else if(stk[tail]==lm and maxcnt==1)
ans+=sum[tail]*(sum[tail]-1)/2+sum[tail],sum[tail--]=0;
else ans+=sum[tail]*(sum[tail]-1)/2+sum[tail]*2,sum[tail--]=0;
}
printf("%lld\n",ans);
return 0;
}
B. marshland
C. party?
D. 半夜
真的不会,难以理解,论文过于生涩.
如果读者有余力请自行钻研..