Loading

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. 半夜

真的不会,难以理解,论文过于生涩.
如果读者有余力请自行钻研..

posted @ 2021-08-19 19:30  AaMuXiiiiii  阅读(32)  评论(0编辑  收藏  举报